使用 Android NFC 向 Java 卡发送超过 261 个字节

Send more than 261 bytes to Java Card with Android NFC

我想通过 NFC (class IsoDep) 将长度为 1699 字节的 APDU 发送到 Java Card 智能卡。我收到错误

java.io.IOException: Transceive length exceeds supported maximum

我的 phone 是三星 Galaxy S7。

我在卡上的小程序中使用了扩展长度。我已经验证该卡支持扩展长度。我通过 pyapdutool 向卡发送一个 4000 字节的 APDU 来测试这个。

我发现当我写这段代码时,结果是false:

final Tag t = (Tag) tag;
myTag = IsoDep.get(t);
boolean result = myTag.isExtendedLengthApduSupported();

我的清单中有这个:

<activity
        android:name=".test"
        android:label="@string/title_test"
        android:launchMode="singleTop"
        android:theme="@style/AppTheme.NoActionBar" >
    <action android:name="android.nfc.action.TAG_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    </intent-filter>
</activity>

如何通过 Android NFC 发送 1699 字节(或任何长度大于 261​​ 字节)的 APDU?

简答:你不能轻易做到这一点。

您已经发现 IsoDep 在您的设备上没有 "support" extended-length APDU(即 isoDep.isExtendedLengthApduSupported() returns false)。事实上,这 而不是 意味着您不能通过 IsoDep object 发送 extended-length APDU。这实际上仅意味着 IsoDep object 不会正确地将 extended-length APDU 拆分为两个以上的 ISO-DEP 块,因此将假定 APDU 长度超过 261 字节超过发送缓冲区大小。您应该仍然能够发送 extended-length 个大小 <= 261 字节的 APDU。

所以 isoDep.isExtendedLengthApduSupported() 实际上表示您是否可以在一个 ISO-DEP 收发器中发送超过 261 个字节。

要克服这个问题,您可以做的是完全不使用 IsoDep object,而是手动实施 ISO-DEP(ISO/IEC 14443- 4 传输协议)在 NfcA object 之上(如果您的卡是基于 NFC-A / ISO/IEC 14443 Type A)或 NfcB object(如果您的卡基于 NFC-B / ISO/IEC 14443 Type B 如果您的设备支持通过 NfcB object).然后,您可以将 extended-length APDU 拆分为 ISO-DEP 块,这些块对于 NFC 控制器的收发缓冲区来说足够小(通常为 253 字节,包括 header 字节,不包括 CRC 字节)。然而,自己处理 ISO-DEP 协议也意味着你必须注意正确的 ISO-DEP 激活,处理块编号、块确认、超时、waiting-time 扩展等。复杂,特别是由于 Android NFC 堆栈的延迟,超时不容易观察到。