javasmartcardIO - 如何在发生超时时取消主机和智能卡之间的读取操作?

javasmartcardIO - How to cancel read action between host and smart card when timeout occur?

我使用 Java 智能卡 IO 框架开发了一个主机应用程序。主机应用程序向卡发送读取命令并等待接收响应。
在此过程中,发生超时(超时值由我定义)。

我想读取过程会在发生超时时停止。我的问题是如何做到这一点?

- 目前,主机应用程序使用基本通道连接到卡。我试图关闭此频道,但出现异常 java.lang.IllegalStateException: Cannot close basic logical channel
- 我也尝试通过调用 channel = card.openLogicalChannel(); 打开逻辑通道,但是当主机发送读取命令时它收到 SW 6D00 - 指令代码不支持或无效。
- 我还尝试通过调用 card.disconnect() 来断开终端和卡的连接,但出现异常

javax.smartcardio.CardException: sun.security.smartcardio.PCSCException: WINDOWS_ERROR_INVALID_HANDLE
    at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:219)
    at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:90)
    at ISO.ISO7816.readRecords(ISO7816.java:234)
    at javasmartcardio.UI.PTCMainFrame.run(PTCMainFrame.java:343)
    at java.lang.Thread.run(Thread.java:745)
Caused by: sun.security.smartcardio.PCSCException: WINDOWS_ERROR_INVALID_HANDLE
    at sun.security.smartcardio.PCSC.SCardTransmit(Native Method)
    at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:189)

I tried to close this channel but I got exception java.lang.IllegalStateException: Cannot close basic logical channel

ISO/IEC 7816-4 第 9 页:

基础频道必须永久可用,即不可关闭。它的频道号是零。


I also tried to open a logical channel by calling channel = card.openLogicalChannel();, but when the host send reading command it receive SW 6D00 - Instruction code not support or invalid.

我想您会收到 0x9000 调用 openLogicalChannel() 方法。如果是这样,你必须先select你的applet在逻辑通道上然后发送READ命令。对于 select 你想要发送 READ 命令的新逻辑通道上的小程序,你只需在 SELECT APDU 命令的 CLA 部分的低半字节中指定通道号。 (即 0X A4 04 00 <AID Len> <AID> 而不是 00 A4 04 00 <AID Len> <AID>- X 是逻辑频道号)。

换句话说,select在基本频道上发送您的小程序并在另一个频道上为同一个小程序发送读取命令是不正确的。当您使用 Manage Channel APDU 命令打开逻辑通道时,该通道上的 selected 小程序是卡的默认 Selected 小程序(不是您已经 selected 的小程序).


关于异常,我想这与您的 reader 有关。

我建议你:

  1. 开启基本逻辑通道以外的逻辑通道
  2. Select 您在该逻辑频道上的小程序。
  3. 通过该逻辑通道发送读取命令。
  4. 超时后关闭此逻辑通道。
  5. 跳转到 1。