NFC Android 截断 APDU 响应字节

NFC Android truncating APDU response bytes

我将 Android 设置为通过 NFC 来回发送 APDU 命令。 APDU 响应字节之一被截断了。

HostAPDUService.sendResponseApdu(bytes[]) 之前的日志语句中打印的响应字节是这样的

I/NfcService: Notifying listener status: DEBUG_APDU_SENT data:7F4982010A81820101009F80023FC39926A237680FFFF47060239F4D240C1EBC424428965FADDBBD0BC3B2CB9BF8952AFF24135C5DCEA7931CEB0BF1406B57BE099DBF7F3A36FA6F20B9B244C1C4131CBFA1D088E1F2298845402B2505E28CA52403EFD09882C361A2F63C30C1FFA3160BAB9BE7CF64E1DA6066EEAAB995B3F627676E4FEF32F9FEA5534E472EBF990F7C964BB9FB36DFE995124AC80C306C796A22840A6FC3871508F1B5CCB063D4DDAD252AA9B4E13219ED4C5EA50FF2BBACA937BB0F9CF80472818AE49DE05E8B66D3863EEF3028325812958099C78CD65919A3660592A0BA5E966D6A01A3DD8242BDA5940146C07AE8475F35C88024DE566112

但在接收端,我只看到收到的前 4 个字符,并且应用程序失败 APDU 响应:

SW=7F49 (No translation available), Nr=0, APDU Response Bytes: 7f 49

知道为什么会这样吗?这是由于扩展的 APDU 功能吗? https://code.google.com/p/android/issues/detail?id=76598

附上整个 APDU 命令跟踪,直到它失败。请注意,相同的代码适用于任何其他接口(如蓝牙、物理卡)等,只是不适用于 NFC Android (HostAPDUService)。

我知道我无法覆盖 HostAPDUService.sendResponseAPDU 所以我找不到截断发生的地方。我确定在发送到此方法之前,我的响应字节没有被截断。

APDU Received: 00A4040008A000000003000000
APDU Sent: 9000
APDU Received: 00CA9F7F
APDU Sent: FF01A3CE00000000000033639D44CFB00C690000000000000000000000000000000000000000000000009000
APDU Received: 80500000085C313D2C8C29F71C
APDU Sent: 000033639D44CFB00C6901020001E3AC80DCF8D08E7D5C5C8C4DCAE29000
APDU Received: 848203001012F927AC6FAC2C247AD0F09679AEC48C
APDU Sent: 9000
APDU Received: 00A4040008A000000003000000
APDU Sent: 9000
APDU Received: 00CA9F7F
APDU Sent: FF01A3CE00000000000033639D44CFB00C690000000000000000000000000000000000000000000000009000
APDU Received: 00A4040008A000000003000000FF
APDU Sent: 9000
APDU Received: 80CA9F7F
APDU Sent: 9F7F2AFF01A3CE00000000000033639D44CFB00C690000000000000000000000000000000000000000000000009000
APDU Received: 00A4040008A000000003000000FF
APDU Sent: 9000
APDU Received: 805000000812D2920F64D6D881
APDU Sent: 000033639D44CFB00C6901020002F8AC3BC0BA50FA6707901F6B6F7A9000
APDU Received: 848203001042E02498FB5BD93AC67DAD9D8EC29373
APDU Sent: 9000
APDU Received: 84D8018150E38DC8FEDD89C6DE48A1C7489CB8EFC83DC1EA0BBCB73E9782EA1593D9A0A327C12702E7EE179ABA888D265C4CAE637338B403B46E41A234564F0F7EC709770178EC32F019F251964C903753766E1DF4
APDU Sent: 0329AD5106993C7EB2649000
APDU Received: 00A404000BA00000030800001000010000
APDU Sent: 9000
APDU Received: 00A404000EE86086480186FA6B81480401010000
APDU Sent: 9000
APDU Received: 8050000008224CDDC4C29B22C3
APDU Sent: 000033639D44CFB00C69030200013C56A721DAB51167FA4320F10AD59000
APDU Received: 84820300101CBA1715E78B70BB20B2032845664977
APDU Sent: 9000
APDU Received: 8420000010C2CBE82EDE23A2984BFDAAC8843E150D
APDU Sent: 9000
APDU Received: 00A4040008A000000003000000FF
APDU Sent: 9000
APDU Received: 805000000885ADBAEFA751CAEB
APDU Sent: 000033639D44CFB00C69030200025FA69462477F571EAA8F0C14AAE49000
APDU Received: 848203001043D948E16FDD63A57FBB6E2EA6673EBB
APDU Sent: 9000
APDU Received: 00A404000BA00000030800001000010000
APDU Sent: 9000
APDU Received: 00A404000EE86086480186FA6B81480401010000
APDU Sent: 9000
APDU Received: 8050000008D15F65B2E12B8199
APDU Sent: 000033639D44CFB00C6903020003048007A68010C2058992616E39529000
APDU Received: 848203001080E36DC19999AB975320ADA23FEF51DD
APDU Sent: 9000
APDU Received: 8400000008309C052FC2AF518700
APDU Sent: 0001000000020000000100000002000000000000000000000000000000000000000000000000000000000000000000000200FFFF0000000000000000000000009000
APDU Received: 841600005841A76F1521DADCAD242B18F13335784DCD34C909C87EFD26D547AF69D00D2881E1CEC3189DC9DB27319B7EB1B454035A2FBF4F5BD453001DB0B95856C544AAEF89F1584495423780CE1209AAEB4F27DCA010CFA3955325FD
APDU Sent: 9000
APDU Received: 841E0000383D3B679C005602D2533321C5B0CB2BB8CB3E9110FDCE4B5990C84010C2EA71D0FF7FEAC9BE1487A72BBC29F52B7FD695FDB792BBE5A8ED78
APDU Sent: 9000
APDU Received: 841A0000080F66BDFF2FD3336F64
APDU Sent: 30218001008101008201008301078401FF8501038601018701008801008901008A01009000
APDU Received: 841A800008C14EECF30745521264
APDU Sent: 30218001008101008201008301078401FF8501038601018701008801008901008A01009000
APDU Received: 841A810008C6EE731C8374C0A264
APDU Sent: 30218001008101008201008301078401FF8501038601018701008801008901008A01009000
APDU Received: 8411010008B1DE5EA8BF8EDF90
APDU Sent: 9000
APDU Received: 841301000862299152D7711722
APDU Sent: 9000
APDU Received: 8412000018433687E78C0B7552BC3939CEF953881623F601ACC92A52C2
APDU Sent: 9000
APDU Received: 8417000008B8C7A9955878DDEB00
APDU Sent: 7F4982010A8182010100BF32292317297991A0B8606A83DF743625BF5AC7708CE798D74DFCEEB13244D7F40CFCA3DEBC928F52CD868674477C52C3F2615B60EBDDAB6D6B4BD1855ADCE7FA0A45F42529571E32385F9E6485333D5CBF24656AF02AEC586FA4A85FA7CA11321106EDCBEDF51108726371BEDA3D75AB5D5F313D042EB0259890697EBE1D12ADFCCAF8477DDA4083AC53590202BF26388CD038D164AE3758CB1139DA9FDDFC74767C5C39DF0DCA5D91AB0C817DCBDDE35A535B6077644C76E74945EB2FA9F1E9365B1B5F91226719848CF365EA75381DFE319461688ACF317A4B49548CFFA71E593100EA9A245DB430FCE79497FD5E63C69398F8266112

呈现的512个十六进制字符的数据意味着接收到256字节的缓冲区。

这可能是您的回复缓冲区大小限制。首先,尝试增加 bytes[] 数组大小,让 API 放入更长的缓冲区。

回复中的TLV数据长度超过256,从TLV数据解析可知:

TLVs:#"7F4982010A81820101009F80023FC39926A237680FFFF47060239F4D240C..6112" # EMV, Tag + Length + Value (TLV) series
- x7F49:#"7F4982010A81820101009F80023FC39926A237680FFFF47060239F4D240C..6112" # ISO 7816, Template, Cardholder public key
  - tag: "7F49"
  - len: "82010A" #  // 266
  - val:#"81820101009F80023FC39926A237680FFFF47060239F4D240C1EBC424428..6112"
    - x81:#"81820101009F80023FC39926A237680FFFF47060239F4D240C1EBC424428..6112" # ISO 7816, RSA Modulus (a number denoted as n coded on x bytes), or DSA First prime (a number denoted as p coded on y bytes), or ECDSA Prime (a number denoted as p coded on z bytes)
      - tag: "81"
      - len: "820101" #  // 257
      - val: "
009F80023FC39926A237680FFFF47060239F4D240C1EBC424428965FADDBBD0BC3B2CB9BF8952AFF24135C5DCEA7931CEB0BF1406B57BE099DBF7F3A36FA6F20B9B244C1C4131CBFA1D088E1F2298845402B2505E28CA52403EFD09882C361A2F63C30C1FFA3160BAB9BE7CF64E1DA6066EEAAB995B3F627676E4FEF32F9FEA5534E472EBF990F7C964BB9FB36DFE995124AC80C306C796A22840A6FC3871508F1B5CCB063D4DDAD252AA9B4E13219ED4C5EA50FF2BBACA937BB0F9CF80472818AE49DE05E8B66D3863EEF3028325812958099C78CD65919A3660592A0BA5E966D6A01A3DD8242BDA5940146C07AE8475F35C88024DE566112"

预期的回复长度:266 字节的模板值 + 3 字节的长度 (0x82010A) + 2 字节的标签 (0x7F49) + 2 字节的 SW1SW2 = 273 字节。

如果可以记录,请提供 APDU 跟踪。

作为第二次尝试,您可以发送获取响应 APDU 命令(指令 "C0")以读取下一块回复缓冲区。类似于:

# 1st Get Response
> 00 C0 00 00 00
< you will get first 256 bytes

# 2nd Get Response
> 00 C0 00 00 00
< you will get next 256 bytes or the rest of data

好的,这是供任何人使用的。

总算APDU命令和缓冲区没有问题。它适用于 Samsung Galaxy S7(Android 版本 6.0.6),不适用于 Note 2 或 Nexus 手机(4.4.X 版本)。 4.4.X 版本 android 手机无法发送整个字节,如果超过则截断。

这个link可以解释这个问题 https://code.google.com/p/android/issues/detail?id=76598