PC/SCではホスト(PCなど)とスマートカード間でAPDU形式のデータがやり取りされます。具体的には、ホストがPC/SCライブラリを介してスマートカードリーダーライターにコマンドを送信し、その中でAPDU形式が使用されます。
ただし、以下のように通信の流れにはいくつかの段階があります:
1. 通信の概要
- ホスト ↔ リーダーライター:
PC/SCライブラリを介して通信します。この通信にはPC/SCのプロトコルが使用され、リーダーライターに命令を送る形となります。 - リーダーライター ↔ スマートカード:
リーダーライターは、ホストから受け取ったPC/SC命令を解釈し、スマートカードに対してAPDU形式でコマンドを送信します。
2. ホストとリーダーライター間でのやり取り
PC/SCのAPI(例: SCardTransmit
関数)を使用して、ホストからカードリーダーライターにAPDUコマンドを送信します。この際の流れは以下の通りです:
- ホストがAPDUコマンドを作成
ホストは、スマートカードに実行させたい操作(例: データの読み書き、認証など)を表すAPDUコマンドを構築します。 - PC/SCライブラリがリーダーライターに送信
PC/SCライブラリがコマンドをリーダーライターに送信します。 - リーダーライターがスマートカードに伝達
リーダーライターは、ホストから受け取ったAPDUコマンドをそのままスマートカードに送信します。 - スマートカードがレスポンスを返す
スマートカードは、受け取ったAPDUに基づいて処理を行い、結果(レスポンスAPDU)をリーダーライターに返します。 - リーダーライターがホストに応答
リーダーライターは、スマートカードからのレスポンスをPC/SCライブラリ経由でホストに送信します。
3. APDUの役割
スマートカードとのやり取りにおいて、APDUは以下のように重要な役割を果たします:
- 操作の指定:
APDUコマンドは、カードに対して実行させたい命令を具体的に指定します(例: 認証、データ読み取り)。 - データの伝達:
スマートカードとの間で交換されるデータは、すべてAPDUの形式で送受信されます。 - 結果の取得:
スマートカードはレスポンスAPDUを返し、コマンドの結果やエラーステータスをホストに通知します。
4. ホスト側のプログラム例(Windows)
以下は、SCardTransmit
を使用してAPDUを送信するシンプルな例です:
SCARDHANDLE hCard; // カードハンドル
SCARD_IO_REQUEST pioSendPci; // プロトコル情報
BYTE pbSendBuffer[] = { 0x00, 0xA4, 0x04, 0x00, 0x02, 0x3F, 0x00 }; // APDUコマンド(例: ファイル選択)
BYTE pbRecvBuffer[256]; // 応答を格納するバッファ
DWORD dwRecvLength = sizeof(pbRecvBuffer); // 応答バッファのサイズ
LONG lRet = SCardTransmit(
hCard, // カードハンドル
&pioSendPci, // プロトコル情報(T=0, T=1など)
pbSendBuffer, // 送信するAPDUコマンド
sizeof(pbSendBuffer), // APDUコマンドの長さ
NULL, // 追加のプロトコル情報(NULLで問題なし)
pbRecvBuffer, // 応答バッファ
&dwRecvLength // 応答データの長さ
);
if (lRet == SCARD_S_SUCCESS) {
// pbRecvBuffer にレスポンスAPDUが格納されている
printf("Response: ");
for (DWORD i = 0; i < dwRecvLength; i++) {
printf("%02X ", pbRecvBuffer[i]);
}
printf("\n");
} else {
printf("Error: %lX\n", lRet);
}
5. まとめ
- APDU形式のデータは、スマートカードとの通信で使用されます。
- ホストとリーダーライター間ではPC/SCプロトコルを介してAPDUが送受信されます。
- PC/SCはホスト側で標準化されたAPIを提供し、開発者がリーダーライターやカードの詳細を意識せずに、APDUを利用したスマートカード操作を実現できます。
これにより、異なるスマートカードリーダーやカード間でも統一的に操作を行うことが可能になります。