【问题标题】:Android NFC communication with Mifare DESFire EV1Android NFC 与 Mifare DESFire EV1 通信
【发布时间】:2013-10-25 12:11:17
【问题描述】:

使用 Nexus 4 和最新的 Android API 级别 18 与 Mifare DESFire EV1 AES 标签通信让我很头疼。为了写入和读取此类标签,遵循 NXP 原生协议,必须遵循以下步骤:

  1. 选择应用程序
  2. 认证
  3. 写或读

为此,我使用 Android 的 IsoDep 类,该类提供对 ISO 14443-4 属性和 I/O 操作的访问。非常奇怪的是,一旦我发送了 select application native 命令,我就会得到一个意想不到的响应。假设我有 AID F4013D 所以我发送:

-> 5AF4013D
<- 6E00

所有可能的响应都必须是一个字节长度(成功0x00 或error_code),不能是两个或更多。因此,成功响应之前的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 不会发生选择应用程序的奇怪响应,但总是会出现写入命令。

【问题讨论】:

    标签: android nfc mifare apdu contactless-smartcard


    【解决方案1】:

    (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 设备将发送 ISO 7816-4 APDU,就像它发送到任何其他 4 类标签一样。因此,如果 NFC 设备在将检测到的标签交给应用程序之前未重置与标签的通信,则应用程序只能使用 ISO 7816-4 APDU 进行通信。但是请注意,我认为这是一个错误,这只发生在同一设备上的 some 激活中。在我看来,在一个特定设备型号上的行为应该是一致的。

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


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

    您的文件的通信设置是否设置为“由 MAC 保护的普通通信”或“完全加密的通信”?在这种情况下,仅仅发送三个数据字节是不够的。相反,您需要发送纯数据加 MAC 或填充、CRC 和加密数据。因此,0xAF 表明该卡需要更多数据。

    编辑: 所以总结下面的 cmets。在发送更多字节后(每次接收到一个字节0xAF 状态代码:AF FF),结果证明卡需要另外 8 个字节。 8 个字节正好是 AES 认证的 CMAC 的大小。因此,通信设置被设置为“由 MAC 保护的普通通信”。

    【讨论】:

    • 感谢您的回答。(1) 如果我没记错的话,PICC 将始终以您通过第一个命令建立的通信类型进行响应。在我的情况下,如果我发送一个5AF4013D 命令,它将是本机的并且没有封装的通信。在这种情况下,答案总是 1 字节长。如果 Android 已经以包装格式与 PICC 建立了先前的联系(除了是一个巨大的错误),恕我直言,它永远不会理解我的本机命令,也不会成功地回答。(2)那是有道理的,但我从一开始就将通信设置设置为普通。
    • 关于 (1):实际上不发送包装命令,而是发送标准 ISO 7816-4 命令来尝试与(潜在)类型 4 标签进行通信。因此,如果在您发送本机命令之前未重置通信,则卡将响应 ISO 7816-4 错误代码。其实6E00并不是什么奇怪的byte+native的成功。相反,它是一个“不支持类”错误(在 ISO 7816-4 中),表明类字节 5A 无效。
    • 关于 (2):这很奇怪。除此之外,我真的不知道那里可能有什么问题。您是否尝试过使用空 AF 命令响应 AF 状态代码?
    • (1) Android 尝试将标签读取为 Type 4 标签当然是意料之中的行为,毕竟它是 NFC 设备,而不是专用的 DESFire/非接触式智能卡读卡器。即使设备在之后没有重置通信也不是真的出乎意料。意想不到的部分(我认为是一个错误,是同一设备上的多个激活之间的不一致)。
    • 还有 8 个字节正好是 CMAC 的长度。所以设置通讯设置时可能出现问题...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多