Javax SmartCardIO:发送 0x00 到读取记录不返回长度

Javax SmartCardIO: Sending 0x00 to Read Record is not returning length

我正在开发个人应用程序,使用 EMV reader 和 Javax SmartCardIO,我正在尝试从智能卡获取所有纯数据,我一直在阅读规范和一些教程,甚至在这里阅读了一些问题,但我想出了一个问题:

我正在尝试获取 SFI 中记录的大小,以便使用该信息迭代所有记录。

我在一些教程中读到我需要发送一个长度为 0 的请求,芯片将用错误代码和正确的记录长度(“6C XX”)来回答,但是在我的卡(Visa 和 AMEX)正在返回另一个转换为卡类型的响应("VISA ELECTRON and AMERICAN EXPRESS"),我没有收到“6c xx”错误。

到目前为止,我的代码如下所示:

byte[] commandArr = {(byte)0x00, (byte)0xB2, (byte)0x01, (byte)0x0C, (byte)0x00};
CommandAPDU commandTest = new CommandAPDU(commandArr);
ResponseAPDU test = this.channel.transmit(commandTest);
System.out.println(hexToAscii(bytesToHex(test.getBytes())));

两张卡都有 01 中第一条 PSE 记录的 SFI(通过 88 标签后的 select PSE 命令获得)。

我是这项技术的新手,现在有点不知所措,欢迎任何帮助。

谢谢!

当您以接触方式与卡建立连接时,您可以选择T0T1两种传输协议之一。它们的主要功能是一样的——与卡通信,只是实现和接口不同。购物车可能支持这些协议之一或两者。不同之处之一是如何从卡中获得响应。在 T0 中,响应可能由两部分(命令)组成。当您得到 SW=61XX 时,您需要执行命令 GetResponce 00C00000XX 到 "read" 响应数据的 xx 长度。在 T1 中,您可以使用 SW 一次获取所有数据。

在你的情况下它似乎使用 T1,所以卡 return 所有数据没有 SW=61XX。

部分文档:

public abstract Card connect(String protocol) throws CardException

要使用的协议("T=0"、"T=1" 或 "T=CL"),或“*”使用任何可用协议进行连接。

public abstract ResponseAPDU transmit(CommandAPDU command) throws CardException

实施应该透明地处理传输协议的工件。例如,当使用 T=0 协议时,应按照 ISO/IEC 7816-4 中的描述进行以下处理:

  • 如果响应 APDU 的 SW1 为 61,则实施应使用 SW2 作为 Lefield 发出 GET RESPONSE 命令。只要接收到 61 的 SW1,就会重复此过程。这些交换的响应主体被串联起来形成最终的响应主体。
  • 如果响应 APDU 是 6C XX,实施应该使用 XX 作为 Le 字段重新发出命令。

除了 Alexander Vaganov 的回答——javax.smartcardio 包自动处理 61XX6CXX 情况,除非被告知不要这样做(sun.security.smartcardio.t0GetResponsesun.security.smartcardio.t1GetResponse系统属性)。

将此属性设置为 false 应该会产生预期的行为(即获取 6CXX 状态字)。

我不知道这方面的任何文档,因此请查看 source code

要禁用上述 61XX6CXX 情况的自动处理,请将以下参数添加到 java 命令行:

-Dsun.security.smartcardio.t0GetResponse=false -Dsun.security.smartcardio.t1GetResponse=false

祝你好运!