You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Java中USB智能卡APDU命令发送成功但响应读取异常咨询

USB智能卡读卡器APDU读取响应异常排查

问题描述

使用Android的UsbManager实现向USB智能卡读卡器发送和读取APDU命令,发送命令功能正常,但读取响应时数据不正确。需要发送的APDU命令为{0x00, (byte) 0x83, 0x00, 0x00, 0X00},上电(powerOn)和下电(powerOff)命令均可正常执行。

发送命令代码

byte[] command = new byte[] {0x00, (byte) 0x83, 0x00, 0x00, 0X00};
String commandHex = bytesToHex(command);
byte[] outBufferXFRBlock = hexStringToByteArray("6F" + "05000000" + "00" + sequenceNumber + "00" + "0000" + commandHex);

int outByteCount = connection.bulkTransfer(outEndpoint, outBufferXFRBlock, outBufferXFRBlock.length, TIMEOUT);

读取响应代码

final byte[] inBuffer = new byte[80];
int inByteCount = connection.bulkTransfer(inEndpoint, inBuffer, inBuffer.length, TIMEOUT);

可能的问题点及排查建议

1. XFRBlock封装格式是否合规

你拼接的XFRBlock头部6F是PC/SC协议中的XFR_BLOCK指令,但需要确认以下细节:

  • sequenceNumber格式:必须是两位十六进制字符串(对应1字节),如果你的sequenceNumber是整数类型,要确保转成两位十六进制(比如数字1要转成"01"而非"1"),否则会导致整个XFRBlock长度偏移,直接引发响应解析错误。
  • 长度字段05000000:这是小端格式的APDU长度(5字节),看起来符合规范,但要确认你的读卡器是否要求大端格式,部分小众读卡器会对长度字节序有特殊要求。

2. 读取响应的缓冲区处理逻辑

  • 不要直接使用完整的inBuffer:bulkTransfer返回的inByteCount是实际读取的有效字节数,必须截取前inByteCount字节进行解析,缓冲区剩余字节可能是未覆盖的垃圾数据。
  • 响应是带XFRBlock封装的:读卡器返回的不是原始APDU响应,需要先解析封装头部:
    1. 检查响应首字节是否为6F(XFR_BLOCK响应标识)
    2. 读取后续4字节并转换字节序,获取响应数据的实际长度
    3. 跳过序列号等头部字段,提取真正的APDU响应数据(包含SW状态字)

3. 命令发送后的完整性验证

  • 确认outByteCount是否等于outBufferXFRBlock.length,如果发送字节数不足,说明命令未完整发送,必然导致响应异常。
  • 部分高波特率读卡器需要发送后短暂等待再读取响应,可以尝试在发送命令后增加100-200ms的延迟(不要超过设置的TIMEOUT值)。

4. APDU命令的上下文合法性

0x00 0x83 0x00 0x00 0x00是GET RESPONSE命令,通常需要配合之前的命令使用(比如之前发送了需要后续获取响应的指令),如果单独发送该命令,读卡器可能返回错误响应,需要确认这个命令在当前读卡器状态下是否合法。

内容的提问来源于stack exchange,提问作者Tolkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:27:16