如何在 Windows 智能卡框架中使用扩展 APDU

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5492843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 16:31:36  来源:igfitidea点击:

How To Use Extended APDU With Windows SmartCard Framework

windowssmartcardwinscard

提问by Ben

I am using WinSCard to read an ISO 7816 compliant smart card (to be specific, it's a PIV card). The card has a picture on it that is roughly 12 KB. Right now, I connect in T=1 mode and use the SCardTransmit function to send my GET DATA APDU command followed by a bunch of GET RESPONSE APDU commands. I end up getting all the data off the card, but it takes more than 40 calls to SCardTransmit because I can only get 256 bytes per call. Each call is taking about half a second to complete, so it ends up taking almost 20 seconds to read 12 KB of data.

我正在使用 WinSCard 读取符合 ISO 7816 的智能卡(具体地说,它是 PIV 卡)。该卡上有一张大约 12 KB 的图片。现在,我以 T=1 模式连接并使用 SCardTransmit 函数发送我的 GET DATA APDU 命令,然后是一堆 GET RESPONSE APDU 命令。我最终从卡上获取了所有数据,但需要对 SCardTransmit 进行 40 多次调用,因为每次调用只能获取 256 个字节。每个调用大约需要半秒才能完成,因此读取 12 KB 数据最终需要近 20 秒。

I think I can do this faster. The NIST spec says that "Retrieval Time for 12.5 kilobytes (KB) of data through the contact interface of the reader shall not exceed 2.0 seconds". The spec makes references to extended length APDU, so I think it is supported, but it's use is not documented. I tried to figure it out, but I can't get it to work.

我想我可以更快地做到这一点。NIST 规范规定“通过阅读器的接触界面检索 12.5 KB 数据的时间不得超过 2.0 秒”。该规范引用了扩展长度的 APDU,所以我认为它是受支持的,但它的使用没有记录。我试图弄清楚,但我无法让它工作。

Here's the current command, which returns 256 bytes with a status of 0x61 0x00, meaning there is more data to get.

这是当前命令,它返回 256 个字节,状态为 0x61 0x00,这意味着还有更多数据要获取。

new byte[] {
     0x00,               // CLA
     0xCB,               // INS
     0x3F,               // P1
     0xFF,               // P2
     0x05,               // Lc
     0x5C, 0x03,         // Data Field
     0x5F, 0xC1, 0x09,   // ... (Data)
     0x00                // Le
};

Part 5.3.2 of the ISO-7815-4 spec says this about encoding Le:

ISO-7815-4 规范的第 5.3.2 部分说明了关于编码 Le:

Case 4E - L= 5 + (B2||B3),(B1)=0 and (B2||B3)=0

  • The Lc field consists of the first 3 bytes where B2 and B3 code Lc (!=0) valued from 1 to 65535
  • B4 to Bl-2 are the Lc bytes of the data field
  • The Le field consists of the last 2 bytes Bl-1 and Bl which code Le valued from 1 to 65536

情况 4E - L= 5 + (B2||B3),(B1)=0 和 (B2||B3)=0

  • Lc 字段由前 3 个字节组成,其中 B2 和 B3 代码 Lc (!=0) 值从 1 到 65535
  • B4到Bl-2是数据字段的Lc字节
  • Le 字段由最后 2 个字节 Bl-1 和 Bl 组成,它们编码 Le 值从 1 到 65536

I took this to mean my command should look this:

我认为这意味着我的命令应该是这样的:

new byte[] {
     0x00,               // CLA
     0xCB,               // INS
     0x3F,               // P1
     0xFF,               // P2
     0x00, 0x00, 0x05,   // Lc
     0x5C, 0x03,         // Data Field
     0x5F, 0xC1, 0x09,   // ... (Data)
     0x00, 0x00          // Le
};

But this doesn't work. I get the response code 0x67 0x00, meaning "Wrong length" and no data is retrieved from the card. Ideas?

但这不起作用。我得到响应代码 0x67 0x00,意思是“长度错误”并且没有从卡中检索到数据。想法?

采纳答案by Kamen Goranchev

The extended APDU that you are trying to send is correct, but it is possible that your card does not support extended APDUs. The Java Card version on the card should be above 2.2.2 to be able to send such commands.

您尝试发送的扩展 APDU 是正确的,但您的卡可能不支持扩展 APDU。卡上的 Java Card 版本应在 2.2.2 以上才能发送此类命令。

回答by Martin Paljak

For more background information (applies to Windows as well): http://pcsclite.alioth.debian.org/ccid_extended_apdu.html

有关更多背景信息(也适用于 Windows):http: //pcsclite.alioth.debian.org/ccid_extended_apdu.html