是否可以在 NFC 卡中实现令牌队列?

Is it possible to implement a token queue in NFC cards?

这个问题专门针对 MIFARE Ultralight C/EV1 或 MIFARE DESFire EV1,甚至是 NTAG 卡。我想实现一个令牌系统,以便每次普通用户读取其中一张卡片时,他们都会获得一个可用令牌;该令牌将从他们正在读取的 NFC 卡中 "pop out"。换句话说,每次读取 NFC 芯片时,它都会从卡的存储中发出不同的可用令牌。这可以实现吗?

更新 2020/06/07>

NTAG 424 支持 "Secure Dynamic Messaging",这可能适用于您的用例。您可以使用 "dynamic part" 存储任何 NDEF 消息,该消息可以选择加密和验证。

引用 NTAG 424 datasheet 的第 9.3 节:

The Secure Dynamic Messaging (SDM) allows for confidential and integrity protected data exchange, without requiring a preceding authentication. NT4H2421Tx supports SDM for reading from one of the StandardData files on the PICC. Secure Dynamic Messaging allows adding security to the data read, while still being able to access it with standard NDEF readers. The typical use case is an NDEF holding a URI and some metadata, where SDM allows this meta-data to be communicated confidentiality and integrity protected toward a backend server.

但请注意,此解决方案无法抵抗某些特定的 tail-replay 场景,引用:

When using SDM, residual risks coming with the Secure Dynamic Messaging for Reading have to be taken into account. As SDM allows free reading of the secured message, i.e. without any up-front reader authentication, anybody can read out the message. This means that also a potential attacker is able to read out and store one or multiple messages, and play them at a later point in time to the verifier. If this residual risk is not acceptable for the system’s use case, the legacy mutual authentication (using challenge response protocol) and subsequent secure messaging should be applied. This would require using an own application and operating outside a standard NDEF read operation. Other risk mitigation may be applied for SDM to limit the residual risk, without completely removing it:

  • Track SDMReadCtr per tag at the verifying side. Reject SDMReadCtr values that have been seen before or that are played out-of-order. This is a minimum requirement any verifier should implement.

  • Limit the time window of an attacker by requiring tags to be presented regularly (e.g. at least once a day) in combination with the previous mitigation.

  • Read out the SDM-protected file more than once. This does not protect against attackers that have read out the valid tag also multiple times and play the received responses in the same sequence.

(请注意,above-mentioned 遗留相互身份验证协议是我在下面的原始答案中描述的)

有个有趣的project implementing the backend server (with tag personalization instructions).

原答案如下:


普通non-programmable智能卡通常提供以下其中一项(或某种组合):

  • fuse bits -- 一个内存区域,其中各个位的值只能以一种方式改变(从零到一或从一到零,但从来没有他们两个)

  • monotonic counter -- 存储在卡上的整数值,个性化后只能在一个方向上改变(增加或减少,但不能同时改变)其中)

  • electronic purse -- 一个整数值,可以由一个实体减少并由另一个实体增加(两个实体都通过不同的密钥证明自己)

None 这些函数直接提供任何不可预测的标记(见注释 1)。

另一个方面是您的 'token collectors' 必须拥有一个允许卡写访问的密钥(能够修改 counters/purse)——这允许他们轻松耗尽所有剩余的保险丝位或counter/purse 值(有效地导致其他 'token collectors' 的拒绝服务条件)。访问控制不能 fine-grained 只允许单个令牌收集(这可能是你想要的)。

使用 可编程智能卡 你可以(半)轻松地实现你需要的任何操作语义——看看 Java 卡(可编程智能卡更贵虽然)。


鉴于您的 'token collectors' 在读取卡片时在线,那么最简单的方法可能是仅使用卡片来证明 'token collector' 在其附近并生成 'token'服务器。

为了证明与卡的接近度,'token collector' 将使用 his/her NFC phone 在服务器和卡之间中继相互身份验证命令。 He/she 不需要知道任何卡片密钥。

任何具有相互身份验证功能的智能卡(例如 Ultralight-C 或 DESFire)都可用于这种情况(见注释 2 和 3)。

DESFire 的通信与此类似:

祝你好运!


注意 1:实际上有些卡可以为他们的电子钱包产生不可预测的 'balance certificate',但我不知道有任何 CL 卡支持这个。

注意 2:具有基于密码的身份验证的卡不适合,因为 'token collectors' 可以很容易地拦截发送到卡上的密码。 MIFARE Classic 不适合,加密密钥需要直接加载到 reader(无法中继)。

注意 3:请注意,通过执行此中继身份验证,您授予 'token collector' 绑定到相应密钥的所有访问权限(尽管 he/she 不知道会话密钥的值)。因此 Ultralight-C 不是一个好的选择,因为从技术上讲,您会给 him/her 一个完全访问卡的权限。同样,不要使用 DESFire 卡主密钥进行中继身份验证——使用 2 个应用程序密钥(具有只有您知道的随机值)创建一个新应用程序,并使用第二个密钥(不是应用程序主密钥)进行中继身份验证。记得也要更改卡片主密钥。

注意 4:DESFire EV2 具有命令中继保护,因此您必须测试它是否适用于您的场景。