能否在NFC卡中实现令牌队列?

7
这个问题是关于MIFARE Ultralight C/EV1, MIFARE DESFire EV1,或者NTAG卡的。 我想实现一个令牌系统,每当普通用户读取这些卡片之一时,他们将获得一个可用的令牌; 该令牌将从他们正在读取的NFC卡中“弹出”。 换句话说,每次读取NFC芯片时,它都会从卡片存储中发出不同的可用令牌。 这个可行吗?

“tokens”是什么类型的?你的问题非常模糊,也许提供一个具体的例子,并使用特定的代码示例逐步说明你想要实现什么会更好。 - henrycjc
1
一个单调计数器值(在许多CL卡中可用)可以用作“令牌”吗?对于“令牌”,有哪些要求(不可预测,特定卡的唯一性等)?应该检查卡的真实性(及其令牌)吗(即您的系统是否需要受到卡克隆/仿真的保护)?我感觉您想把那些“令牌发射”卡放在某个地方,然后用户会带着他们的读卡器(NFC手机)去收集这些令牌(就像地理缓存)--是这样吗? - vlp
没错,@vlp,你猜对了。我还没有考虑太多有关令牌生成的事情,但是系统应该可以避免复制和预测。 - softzer0
1
你的用户在获取“令牌”时是否在线?如果是的话,你的服务器可以与卡通信(用户的 NFC 读卡器将中继通信),以证明用户在卡附近(服务器将拥有卡密钥来验证卡的有效性)。然后您可以在您的服务器上自由生成用户的“令牌”。 - vlp
是的@vlp,我考虑让用户读取卡片,获取令牌并在线验证以证明他在那个位置是正确的。我还考虑到另一个人将具有写入访问权限,以填充卡片中从服务器生成的新令牌,以便稍后进行验证。 - softzer0
1
请查看此文章。其中使用了一种生成卡片随机数的技术。 - Alexander
1个回答

5

更新于2020/06/07>

NTAG 424支持“安全动态消息”,可能适用于您的使用情况。您可以存储带有“动态部分”的任何NDEF消息,该部分可选择加密和身份验证。

引用NTAG 424 datasheet的第9.3节:

安全动态消息(SDM)允许进行机密和完整性保护的数据交换,而无需先进行身份验证。 NT4H2421Tx支持从PICC上的StandardData文件之一读取SDM。安全动态消息允许对读取的数据添加安全性,同时仍然能够使用标准NDEF读取器访问它。典型用例是一个包含URI和一些元数据的NDEF,其中SDM允许将这些元数据与后端服务器进行机密和完整性保护的通信。

但请注意,这种解决方案并不适用于某些特定的尾部重放场景,例如:

在使用SDM时,必须考虑到与阅读安全动态消息相关的剩余风险。由于SDM允许自由阅读受保护的消息,即没有任何预先的读者身份验证,因此任何人都可以读取该消息。这意味着潜在攻击者也能够读取并存储一条或多条消息,并在以后的时间点上播放它们给验证器。如果该系统的使用情况不能接受这种剩余风险,则应用遗留的互相认证(使用挑战响应协议)和随后的安全消息传递。这将需要使用自己的应用程序,并在标准NDEF读操作之外运行。其他降低SDM剩余风险的方法可以应用,而不完全消除它:
- 在验证方对每个标签追踪 SDMReadCtr。拒绝已经看过或播放顺序错误的SDMReadCtr值。这是任何验证器都应实施的最小要求。 - 通过要求定期(例如每天至少一次)呈现标签来限制攻击者的时间窗口,结合前面的缓解措施。 - 多次读取SDM保护的文件。这不能保护那些已经多次读取有效标签并按照相同顺序播放接收到的响应的攻击者。

(请注意,上述传统的双向认证协议是我在下面原始答案中描述的内容)

有一个有趣的实现后端服务器的项目(带有个性化指令标签)。

以下是原始答案:


普通的非可编程智能卡通常提供以下一种或几种组合:

  • 烧丝位 -- 存储区域中的每个位的值只能以一种方式改变(从零到一或从一到零,但不能同时发生)

  • 单调计数器 -- 存储在卡上的整数值在个性化后只能朝一个方向改变(增加或减少,但不能同时进行)

  • 电子钱包 -- 一个整数值可以由一个实体减少并由另一个实体增加(两个实体都通过不同的秘密钥匙证明自己)

这些功能都没有直接提供任何不可预测的令牌(请参见注1)。

另一个方面是,您的“令牌收集器”必须拥有允许卡片写入访问的密钥(以便能够修改计数器/电子钱包)-- 这使得他们可以轻松耗尽所有剩余的烧丝位或计数器/电子钱包值(有效地导致其他“令牌收集器”出现拒绝服务状态)。访问控制无法细分为仅允许单个令牌收集(这可能是您想要的情况)。

使用可编程智能卡,您可以(半)轻松地实现任何所需的操作语义 - 查看Java Card(可编程智能卡的成本更高)。


如果您的“令牌收集器”在读取卡片时在线,那么最简单的方法可能是仅使用卡片来证明“令牌收集器”在其附近,并在服务器上生成“令牌”。
为了证明与卡的接近,'token collector'将使用他/她的NFC手机在服务器和卡之间中继互认命令。他/她不需要知道任何卡密钥。
任何具有互认功能的智能卡(例如Ultralight-C或DESFire)都可在此场景中使用(参见注2和注3)。
DESFire的通信看起来类似于此:

Simplified sequence diagram

祝好运!


注意1:实际上有些卡可以为它们的电子钱包生成不可预测的“余额证书”,但我不知道任何支持此功能的CL卡。

注意2:基于密码的身份验证不适合作为“令牌收集器”,因为“令牌收集器”可以轻松截取发送到卡片的密码。MIFARE Classic也不适合,因为加密密钥需要直接加载到读卡器中(中继不可能)。

注意3:请注意,通过执行这种中继身份验证,您授予“令牌收集器”与相应密钥绑定的所有访问权限(尽管他/她不知道会话密钥的值)。因此,Ultralight-C不是一个好选择,因为您从技术上讲会完全授予他/她访问卡的权限。同样,不要使用DESFire卡主密钥进行中继身份验证--创建一个具有2个应用程序密钥的新应用程序(只有您知道的随机值),并使用第二个密钥(而不是应用程序主密钥)进行中继身份验证。记得同时更改卡主密钥。

注意4:DESFire EV2具有命令中继保护,因此您需要测试它在您的情况下是否有效。


1
@MikiSoft,我不知道是否有没有可编程智能卡的解决方案。这完全取决于您的威胁模型。如果您的“令牌收集器”大多是诚实的(并且没有涉及到金钱——例如在一个有趣/业余项目中),那么最简单的方法是将NTAG与指向卡片的URL存储起来。这样,您就不需要任何额外的应用程序来进行“令牌收集”——“令牌收集器”将被重定向到您服务器上的固定URL,您可以在那里给他们“令牌”。您可以通过要求他们提供一些“密码”来增强此功能,该密码可能会被打印/写在卡片上...或附近(用于弱证明...)。 - vlp
1
...在正确的位置上出现)。您可以定期更改这些密码。对于少数不诚实的收藏家,他们可能会通过损坏或窃取卡片来造成伤害,这可能无法避免。如果这是一个严肃的项目(游戏、忠诚度计划等),那么您应该考虑使用可编程智能卡。 - vlp
1
一个简单的解决方案是使用任何可写的令牌作为“草稿本”——即您的服务器会给“令牌收集器”一个用于单个(随机)卡片存储器块的密钥。他会读取它并发布其内容(由服务器检查预期值)。然后服务器会发送新数据以写入此块。这样,您可以为任何单个收集器提供对单个块(或文件)的读/写访问权限,因此不诚实的收集器将无法造成太多损害(他/她无法更改没有密钥的块)。读取的值不能重复使用,因为它们每次都不同... - vlp
1
如果收集器给出的块值与预期值不匹配,则有两种情况 - 当前收集器不诚实或读取相同块的上一个收集器不诚实(他/她没有写入正确的值)。您可以通过要求他读取另一个随机块来检查当前收集器的诚实度。如果他/她能够读取它,那么他/她就在卡的附近,并且(可能)是诚实的。单个卡可以有多个块(每个块都有不同的密钥),因此单个恶作剧收集器... - vlp
1
@MikiSoft的Java Card实现应该遵循NFC Forum Type 4标签规范,这样它就可以工作(我从未尝试过),请参见此问题 - vlp
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接