安卓如何与Mifare DESFire EV1进行NFC通讯

6
使用Nexus 4和最新的Android API级别18与Mifare DESFire EV1 AES标签通信让我感到头疼。为了读写此类标签,必须遵循NXP原生协议,按照以下步骤操作:
  1. 选择应用程序
  2. 认证
  3. 写入或读取
为此,我使用Android的IsoDep类,该类提供对ISO 14443-4属性和I/O操作的访问。非常奇怪的是,一旦我发送选择应用程序本地命令,我会收到一个意外的响应。假设我有AID F4013D,所以我发送:
-> 5AF4013D
<- 6E00

所有可能的响应必须是一个字节长度(成功0x00或错误代码),永远不会是两个或更多。因此,成功响应前的0x6E绝对是意外的。它并不总是发生,当它不发生且正常工作时,选择应用程序和身份验证过程都正常工作。但是,一旦经过身份验证,写入命令就没有正确的行为,所有写入命令都以来自PICC的0xAF结束,而不是成功的0x00。看起来像是PICC期望一些额外的数据,而实际上不需要(我发送了正确长度的有效负载)。如果我发送任何其他命令,我会收到一个0xCA(命令中止)错误代码。
-> 5AF4013D
<- 00 /*Success*/
-> AA01
<- AFA8394ED57A5E83106B4EE72FD2BB0CC4
-> AF148F525E1DDE0AD6AB60B4B615552475C91F2E8D89B8523E4465113DD5BD19C6 
<- 0066D255C93F2F492AFE3715C88964F1BD /*Authentication success*/
-> 3D02000000030000222222 /*Write 3 bytes to file nº2*/
<- AF /*Unexpected, 0x00 was expected*/

作为正常情况,如果我使用个人读卡器(非Android NFC)发送这些类型的命令,它总是能够正常工作。似乎在Android NFC API中有一些奇怪的事情发生,当它应该只是一个原始数据传输器,永远不会解释或修改数据。

我也尝试了使用ISO 7816-4 APDU结构,结果相同。有趣的是,在Galaxy Nexus上没有发生选择应用程序的奇怪响应,但写入命令则总是会出现。

1个回答

9

(1) 关于状态码6E00的第一部分:

6E 00不是一个“奇怪的字节0x6E+成功状态码0x00”。相反,它是一个响应APDU状态字6E 00(“类别不支持”)。这表明先前使用基于APDU的访问与卡片进行了通信(例如,Android本身尝试将卡片读取为类型4标签并在此之后未重置连接)。因此,卡片将期望所有进一步的通信均采用ISO 7816-4 APDU。在这种情况下(即如果您收到类似6E 00的ISO 7816-4状态码),您可以通过简单包装您的本机命令来继续使用DESFire APDU包装命令。

编辑:实际上,这在NFC设备上是某种预期的行为。想法是NFC设备会自动扫描检测到的标签以获取NDEF消息。对于DESFire卡而言,NFC设备将检测到该卡作为潜在的类型4标签。因此,NFC设备将像发送给任何其他类型4标签一样发送ISO 7816-4 APDU。因此,如果NFC设备在将检测到的标签交给应用程序之前不重置与标签的通信,则应用程序只能使用ISO 7816-4 APDU进行通信。但是请注意,我认为这仅发生在同一设备上的某些激活中,这是一个错误。在我看来,在一个特定的设备型号上的行为应该是一致的。

编辑:虽然我不认为这种行为是错误,但实际上它是由于Android的NFC堆栈中已知的错误(#58773)造成的,适用于具有Broadcom NFC控制器的设备。在受影响的设备上,自动存在检查以定时间隔发送ISO 7816-4 APDU,这会导致DESFire卡切换到ISO 7816-4 APDU模式。


(2) 关于(意外的)响应代码0xAF的第二部分:

您的文件通信设置是否设置为“通过MAC保护的纯文本通信”或“完全加密通信”?在这种情况下,仅发送三个数据字节将不足够。相反,您需要发送明文数据加上MAC或填充的、带CRC的和加密的数据。因此,0xAF表示卡片需要进一步的数据。

编辑:因此,总结以下评论。在发送更多字节(每个接收到的0xAF状态码一个字节:AF FF)之后,结果发现卡片需要8个字节。 8个字节正好是AES身份验证的CMAC大小。因此,通信设置被设置为“通过MAC保护的纯文本通信”。


关于(2):那很奇怪。除此之外,我真的不知道可能出了什么问题。你尝试过用空的AF命令响应AF状态码吗? - Michael Roland
(1) 所以应该将其视为 Android 的一个 bug,尝试读取标签但未重置通信? (2) 是的,我这样做了,它进入了一个无限循环的 AF。 - GoRoS
1
(1)Android 尝试将标签读取为 Type 4 标签,这当然是预期行为,毕竟它是 NFC 设备,而不是专用的 DESFire/非接触式智能卡读卡器。即使设备在此后没有重置通信,也并不是真正意义上的意外。意外之处(我认为这是一个 bug)在于同一设备上多次激活之间的不一致性。 - Michael Roland
1
仍然,8个字节恰好是CMAC的长度。因此,在设置通信设置时可能出现了问题... - Michael Roland
你是对的,当我说它只是普通的时候我错了,它带有MAC,所以像你说的那样,在写入数据后需要MAC。现在唯一要知道的就是Android和问题(1)到底发生了什么。无论如何,感谢你引导我找到解决方案,我会给你正确的答案! - GoRoS
显示剩余4条评论

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