WinSCard を使用して、ISO 7816 準拠のスマート カード (具体的には PIV カード) を読み取っています。カードには、約 12 KB の画像があります。現在、T=1 モードで接続し、SCardTransmit 関数を使用して GET DATA APDU コマンドを送信し、その後に一連の GET RESPONSE APDU コマンドを送信しています。カードからすべてのデータを取得することになりますが、1 回の呼び出しで 256 バイトしか取得できないため、SCardTransmit を 40 回以上呼び出す必要があります。各呼び出しが完了するまでに約 0.5 秒かかるため、12 KB のデータを読み取るのに約 20 秒かかることになります。
私はこれをより速く行うことができると思います。NIST 仕様では、「リーダーの接触インターフェイスを介した 12.5 キロバイト (KB) のデータの取得時間は 2.0 秒を超えてはならない」と規定されています。仕様では拡張長の APDU が参照されているため、サポートされていると思いますが、その使用法は文書化されていません。私はそれを理解しようとしましたが、うまくいきません。
これは現在のコマンドで、ステータスが 0x61 0x00 の 256 バイトを返します。これは、取得するデータがまだあることを意味します。
new byte[] {
0x00, // CLA
0xCB, // INS
0x3F, // P1
0xFF, // P2
0x05, // Lc
0x5C, 0x03, // Data Field
0x5F, 0xC1, 0x09, // ... (Data)
0x00 // Le
};
ISO-7815-4 仕様のパート 5.3.2 は、Le のエンコーディングについて次のように述べています。
ケース 4E - L= 5 + (B2||B3),(B1)=0 および (B2||B3)=0
- Lc フィールドは最初の 3 バイトで構成され、B2 と B3 は 1 ~ 65535 の値の Lc (!=0) をコードします。
- B4 から Bl-2 は、データ フィールドの Lc バイトです。
- Le フィールドは、最後の 2 バイトの Bl-1 と Bl で構成され、1 ~ 65536 の値の Le をコード化します。
これは、コマンドが次のようになることを意味すると考えました。
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
};
しかし、これはうまくいきません。応答コード 0x67 0x00 を受け取ります。これは「長さが間違っています」という意味で、カードからデータが取得されません。アイデア?