ICカードへAPDUコマンドを送信すると、必ず2バイトの返り値が得られます。 その値の意味をメッセージで表示することでデバッグなどの作業が捗るので、APDUレスポンスの一覧と、その一部の意味を表示するPythonコードを紹介します。
Pythonで定義した関数 get_status_msg(sw1, sw2)
は引数1に1バイト目の値、引数2に2バイト目の値を渡すと、値の意味を文字列で返す関数です。
全てのレスポンスを拾うと巨大な関数になってしまうので重要そうなメッセージだけを表示するようにしています。
pyscardと一緒に使用する例を以下に示します。
from smartcard.util import toHexString
from smartcard.System import readers as get_readers
readers = get_readers()
print(readers)
conn = readers[0].createConnection()
conn.connect()
send_data = [0xFF, 0xCA, 0x00, 0x00, 0x00]
recv_data, sw1, sw2 = conn.transmit(send_data)
def get_status_msg(sw1, sw2):
if sw1 == 0x90 and sw2 == 0x00:
return "I: 正常終了"
if sw1 == 0x61:
return f"I: 出力成功。残り{int(sw2)}バイトが出力可能です。"
if sw1 == 0x62:
if sw2 == 0x81: return "W: 出力データに異常があります。"
if sw2 == 0x83: return "W: 選択したファイルは無効になりました。"
return "W: 不揮発性メモリの状態は変更されていません。"
if sw1 == 0x63:
if sw2 == 0x81: return "W: ファイルの書き込み可能領域が不足しています。"
if (sw2 >> 4) == 0xc: return f"W: 検証失敗。残り{int(sw2 & 0x0f)}回リトライ可能です。"
return "W: 不揮発性メモリの状態は変化しています。"
if sw1 == 0x64:
if sw2 == 0x01: return "E: コマンドはタイムアウトしました。"
return "E: 不揮発性メモリの状態は変更されていません。"
if sw1 == 0x65:
if sw2 == 0x01: return "E: 書き込みエラーが発生しました。"
return "E: 不揮発性メモリの状態は変化しています。"
if sw1 == 0x66:
if sw2 == 0x00: return "E: 受信時にタイムアウトエラーが発生しました。"
if sw2 == 0x01: return "E: 受信時にパリティチェックエラーが発生しました。"
if sw2 == 0x02: return "E: 受信時にチェックサムエラーが発生しました。"
if sw2 == 0x69: return "E: 不正な暗号化/復号パディングが含まれています。"
return "E: セキュリティエラーが発生しました。"
if sw1 == 0x67:
if sw2 == 0x00: return "E: データ長(Lc/Leフィールド)が不正です。"
return "E: データ長が不正です。"
if sw1 == 0x68:
return "E: CLAの機能は対応していません。"
if sw1 == 0x69:
if sw2 == 0x81: return "E: ファイル構造と互換性のないコマンドです。"
if sw2 == 0x82: return "E: セキュリティ条件が満たされていません。"
if sw2 == 0x83: return "E: 認証方法がブロックされています。"
if sw2 == 0x84: return "E: 参照データがブロックされました。"
if sw2 == 0x85: return "E: コマンドの使用条件を満たしていません。"
if sw2 == 0x86: return "E: ファイルが存在しません。"
if sw2 == 0x87: return "E: セキュアメッセージングに必要なデータオブジェクトが存在しません。"
if sw2 == 0x88: return "E: セキュアメッセージングのデータオブジェクトが不正です。"
return "E: コマンドは許可されていません。"
if sw1 == 0x6a:
if sw2 == 0x80: return "E: データフィールドのパラメータが正しくないです。"
if sw2 == 0x81: return "E: サポートされていない機能です。"
if sw2 == 0x82: return "E: ファイルが存在しません。"
if sw2 == 0x83: return "E: レコードが存在しません。"
if sw2 == 0x84: return "E: レコードまたはファイルのメモリ容量が不足しています。"
if sw2 == 0x85: return "E: LcはTLV構造と一致しません。"
if sw2 == 0x86: return "E: P1またはP2パラメータが正しくありません。"
if sw2 == 0x87: return "E: LcがP1-P2と一致しない。"
if sw2 == 0x88: return "E: 参照データが見つかりません。"
if sw2 == 0x89: return "E: ファイルが既に存在します。"
if sw2 == 0x8A: return "E: DF名が既に存在します。"
return "E: パラメータの値が間違っています。"
if sw1 == 0x6b:
return "E: パラメータの値が間違っています。"
if sw1 == 0x6d:
return "E: 命令コード(INS)が不正です。"
if sw1 == 0x6e:
return "E: 命令クラス(CLA)が不正です。"
if sw1 == 0x6f:
return "E: 内部エラーが発生しました。"
return ""
print(get_status_msg(sw1, sw2))
print(toHexString(recv_data))
以下おまけ
APDUレスポンス一覧
種類は3個あり、それぞれ I: 情報(Infomation)、W: 警告(Warning)、E: エラー(Error) です。
SW1 | SW2 | 種類 | 内容 |
---|---|---|---|
6- | – | E | クラスはサポートされていません。 |
61 | – | I | 応答バイトはまだ利用可能 |
61 | XX | I | コマンドは正常に実行されました。「XX」バイトのデータが使用可能であり、GETRESPONSEを使用して要求できます。 |
62 | – | W | 不揮発性メモリの状態は変更されていません |
62 | 00 | W | 情報が提供されていません(NV-Ramは変更されていません) |
62 | 01 | W | NV-RAMは変更されていません。 |
62 | 81 | W | 返されたデータの一部が破損している可能性があります |
62 | 82 | W | Leバイトを読み取る前にファイル/レコードの終わりに達しました |
62 | 83 | W | 選択したファイルが無効になりました |
62 | 84 | W | 選択したファイルが無効です。FCIがISOに従ってフォーマットされていない |
62 | 85 | W | カードのセンサーから利用できる入力データがありません。R3bc用にスレーブされた財布エンジンはありません |
62 | A2 | W | 間違ったR-MAC |
62 | A4 | W | カードがロックされています(reset中) |
62 | CX | W | 値xのカウンター(コマンドに依存) |
62 | F1 | W | 間違ったC-MAC |
62 | F3 | W | 内部リセット |
62 | F5 | W | デフォルトのエージェントがロックされています |
62 | F7 | W | カード所有者がロックされています |
62 | F8 | W | 地下室は現在のエージェントです |
62 | F9 | W | CALCキーセットのブロックが解除されていません |
62 | FX | W | – |
62 | XX | W | RFU |
63 | – | W | 不揮発性メモリの状態が変更されました |
63 | 00 | W | 情報が提供されていません(NV-Ramが変更されました) |
63 | 81 | W | 最後の書き込みでいっぱいになったファイル。ロード/更新は許可されていません。 |
63 | 82 | W | カードキーはサポートされていません。 |
63 | 83 | W | リーダーキーはサポートされていません。 |
63 | 84 | W | プレーンテキスト送信はサポートされていません。 |
63 | 85 | W | セキュアな送信はサポートされていません。 |
63 | 86 | W | 揮発性メモリは使用できません。 |
63 | 87 | W | 不揮発性メモリは使用できません。 |
63 | 88 | W | キー番号が無効です。 |
63 | 89 | W | キーの長さが正しくありません。 |
63 | C0 | W | 失敗を確認します。残りはありません。 |
63 | C1 | W | 失敗を確認し、残り1回試行します。 |
63 | C2 | W | 失敗を確認し、残り2回試行します。 |
63 | C3 | W | 失敗を確認し、残り3回試行します。 |
63 | CX | W | カウンターが値 'x'(0 = x = 15)に達しました(コマンドによって異なります)。 |
63 | F1 | W | より多くのデータが期待されます。 |
63 | F2 | W | より多くのデータが予想され、プロアクティブなコマンドが保留中です。 |
63 | FX | W | – |
63 | XX | W | RFU |
64 | – | E | 不揮発性メモリの状態は変更されていません |
64 | 00 | E | 情報が提供されていません(NV-Ramは変更されていません) |
64 | 01 | E | コマンドタイムアウト。カードに必要な即時応答。 |
64 | XX | E | RFU |
65 | – | E | 不揮発性メモリの状態が変更されました |
65 | 00 | E | 情報がありません |
65 | 01 | E | 書き込みエラー。メモリ障害。EEPROMの書き込みまたは読み取りに問題がありました。他のハードウェアの問題もこのエラーを引き起こす可能性があります。 |
65 | 81 | E | メモリ障害 |
65 | FX | E | – |
65 | XX | E | RFU |
66 | – | S | |
66 | 00 | S | 受信中のエラー(タイムアウト) |
66 | 01 | S | 受信中のエラー(文字パリティエラー) |
66 | 02 | S | 間違ったチェックサム |
66 | 03 | S | FCIのない現在のDFファイル |
66 | 04 | S | 現在のDFの下にSFまたはKFはありません |
66 | 69 | S | 暗号化/復号化のパディングが正しくない |
66 | XX | S | – |
67 | – | E | |
67 | 00 | E | 間違った長さ |
67 | XX | E | 長さが正しくない(手順)(ISO7816-3) |
68 | – | E | CLAの機能はサポートされていません |
68 | 00 | E | 情報がありません(リクエスト機能はカードでサポートされていません) |
68 | 81 | E | 論理チャネルはサポートされていません |
68 | 82 | E | 安全なメッセージングはサポートされていません |
68 | 83 | E | チェーンの最後のコマンドが必要です |
68 | 84 | E | コマンドチェーンはサポートされていません |
68 | FX | E | – |
68 | XX | E | RFU |
69 | – | E | コマンドは許可されていません |
69 | 00 | E | 情報が提供されていません(コマンドは許可されていません) |
69 | 01 | E | コマンドは受け入れられません(非アクティブ状態) |
69 | 81 | E | コマンドはファイル構造と互換性がありません |
69 | 82 | E | セキュリティ条件が満たされていません。 |
69 | 83 | E | 認証方法がブロックされました |
69 | 84 | E | 参照データは可逆的にブロック(無効化)されました |
69 | 85 | E | 使用条件が満たされていません。 |
69 | 86 | E | コマンドは許可されていません(現在のEFはありません) |
69 | 87 | E | 予期されるセキュアメッセージング(SM)オブジェクトがありません |
69 | 88 | E | 不正なセキュアメッセージング(SM)データオブジェクト |
69 | 8D | 予約済み | |
69 | 96 | E | データを再度更新する必要があります |
69 | E1 | E | 現在有効なプロファイルのPOL1は、このアクションを防ぎます。 |
69 | F0 | E | アクセス拒否 |
69 | F1 | E | 許可が拒否されました–特権がありません |
69 | FX | E | – |
69 | XX | E | RFU |
6A | – | E | 間違ったパラメータP1-P2 |
6A | 00 | E | 情報が提供されていません(バイトP1および/またはP2が正しくありません) |
6A | 80 | E | データフィールドのパラメータが正しくありません。 |
6A | 81 | E | 機能はサポートされていません |
6A | 82 | E | ファイルが見つかりません |
6A | 83 | E | 記録が見当たりませんでした |
6A | 84 | E | レコードまたはファイルに十分なメモリスペースがありません |
6A | 85 | E | LcがTLV構造と矛盾している |
6A | 86 | E | P1またはP2パラメータが正しくありません。 |
6A | 87 | E | LcがP1-P2と矛盾している |
6A | 88 | E | 参照データが見つかりません |
6A | 89 | E | ファイルが既に存在します |
6A | 8A | E | DF名はすでに存在します。 |
6A | F0 | E | パラメータ値が間違っています |
6A | FX | E | – |
6A | XX | E | RFU |
6B | – | E | |
6B | 00 | E | 間違ったパラメータP1-P2 |
6B | XX | E | 参照が正しくありません(プロシージャバイト)(ISO 7816-3) |
6C | – | E | 間違った長さのル |
6C | 00 | E | P3の長さが正しくありません。 |
6C | XX | E | Leの長さの値が正しくありません。「xx」は正しい正確なLeです |
6D | – | E | |
6D | 00 | E | 命令コードがサポートされていないか無効です |
6D | XX | E | 命令コードがプログラムされていないか無効です(プロシージャバイト)、(ISO 7816-3) |
6E | – | E | |
6E | 00 | E | クラスはサポートされていません |
6E | XX | E | 命令クラスはサポートされていません(プロシージャバイト)、(ISO 7816-3) |
6F | – | E | 内部例外 |
6F | 00 | E | コマンドが中止されました – より正確な診断は不可能です(オペレーティングシステムエラーなど)。 |
6F | FF | E | カードが死んでいる(使いすぎなど) |
6F | XX | E | 正確な診断なし(手順バイト)、(ISO 7816-3) |
9- | 00 | ||
90 | 00 | I | コマンドは正常に実行されました(OK)。 |
90 | 04 | W | PINが正常に確認されなかった、3回以上のPINの試行が残っている |
90 | 08 | キー/ファイルが見つかりません | |
90 | 80 | W | ブロック解除試行カウンターがゼロに達しました |
91 | 00 | OK | |
91 | 01 | States.activity、States.lock Status、またはStates.lockableの値が間違っています | |
91 | 02 | トランザクション数が制限に達しました | |
91 | 0C | 変更なし | |
91 | 0E | コマンドを完了するにはNVメモリが不足しています | |
91 | 1C | コマンドコードはサポートされていません | |
91 | 1E | CRCまたはMACがデータと一致しません | |
91 | 40 | 無効なキー番号が指定されました | |
91 | 7E | コマンド文字列の長さが無効です | |
91 | 9D | 要求されたコマンドを許可しない | |
91 | 9E | パラメータの値が無効です | |
91 | A0 | 要求されたAIDがPICCに存在しません | |
91 | A1 | アプリケーション内の回復不能なエラー | |
91 | AE | 認証ステータスが要求されたコマンドを許可していません | |
91 | AF | 追加のデータフレームが送信される予定です | |
91 | BE | 境界外 | |
91 | C1 | PICC内の回復不能なエラー | |
91 | CA | 前のコマンドが完全に完了していません | |
91 | CD | 回復不能なエラーによりPICCが無効になりました | |
91 | CE | アプリケーションの数は28に制限されています | |
91 | DE | ファイルまたはアプリケーションはすでに存在します | |
91 | EE | 電力損失のため、NV書き込み操作を完了できませんでした | |
91 | F0 | 指定されたファイル番号が存在しません | |
91 | F1 | ファイル内の回復不能なエラー | |
92 | 0x | I | 'x'の試行後、EEPROMへの書き込みは成功しました。 |
92 | 10 | E | 不十分なメモリ。利用可能なストレージはこれ以上ありません。 |
92 | 40 | E | EEPROMへの書き込みが失敗しました。 |
93 | 01 | 整合性エラー | |
93 | 02 | 候補S2が無効 | |
93 | 03 | E | アプリケーションは永続的にロックされています |
94 | 00 | E | EFが選択されていません。 |
94 | 01 | 補通貨コードが財布の通貨と一致しません | |
94 | 02 | 補量が多すぎます | |
94 | 02 | E | アドレス範囲を超えました。 |
94 | 03 | 候補量が少なすぎる | |
94 | 04 | E | FIDが見つからない、レコードが見つからない、または比較パターンが見つかりません。 |
94 | 05 | データフィールドの問題 | |
94 | 06 | E | 必要なMACが利用できません |
94 | 07 | 悪い通貨:財布エンジンにはR3bc通貨のスロットがありません | |
94 | 08 | R3bc通貨は財布エンジンではサポートされていません | |
94 | 08 | E | 選択したファイルタイプがコマンドと一致しません。 |
95 | 80 | シーケンスが悪い | |
96 | 81 | スレーブが見つかりません | |
97 | 00 | PINがブロックされ、ブロック解除試行カウンターが1または2 | |
97 | 02 | メインキーがブロックされています | |
97 | 04 | PINが正常に確認されなかったが、3回以上のPINの試行が残っている | |
97 | 84 | ベースキー | |
97 | 85 | 制限を超えました – C-MAC鍵 | |
97 | 86 | SMエラー – 制限を超えました – R-MAC鍵 | |
97 | 87 | 制限を超えました – シーケンスカウンター | |
97 | 88 | 制限を超えました – R-MACの長さ | |
97 | 89 | サービスは利用できません | |
98 | 02 | E | PINが定義されていません。 |
98 | 04 | E | アクセス条件が満たされていないため、認証に失敗しました。 |
98 | 35 | E | ASKRANDOMまたはGIVERANDOMが実行されていません。 |
98 | 40 | E | PINの確認に失敗しました。 |
98 | 50 | E | 制限に達したため、INCREASEまたはDECREASEを実行できませんでした。 |
98 | 62 | E | 認証エラー、アプリケーション固有(MACが正しくない) |
99 | 00 | 1PINを残してみてください | |
99 | 04 | PINが正常に確認されていません、1つのPINを残してください | |
99 | 85 | 間違ったステータス – カード所有者のロック | |
99 | 86 | E | 特権がありません |
99 | 87 | PINがインストールされていません | |
99 | 88 | 間違ったステータス – R-MAC状態 | |
9A | 00 | 2PIN左を試す | |
9A | 04 | PINが正常に確認されていません、2PINを残してみてください | |
9A | 71 | 間違ったパラメーター値 – 二重スパイAID | |
9A | 72 | 間違ったパラメータ値 – 二重スパイタイプ | |
9D | 05 | E | 証明書の種類が正しくありません |
9D | 07 | E | 不正なセッションデータサイズ |
9D | 08 | E | DIRファイルのレコードサイズが正しくありません |
9D | 09 | E | FCIレコードサイズが正しくありません |
9D | 0A | E | コードサイズが正しくありません |
9D | 10 | E | アプリケーションをロードするためのメモリが不足しています |
9D | 11 | E | 無効なAID |
9D | 12 | E | 重複するAID |
9D | 13 | E | 以前にロードされたアプリケーション |
9D | 14 | E | アプリケーション履歴リストがいっぱい |
9D | 15 | E | アプリケーションが開いていません |
9D | 17 | E | 無効なオフセット |
9D | 18 | E | アプリケーションはすでにロードされています |
9D | 19 | E | 無効な証明書 |
9D | 1A | E | 無効な署名 |
9D | 1B | E | 無効なKTU |
9D | 1D | E | MSMコントロールが設定されていません |
9D | 1E | E | アプリケーションの署名が存在しません |
9D | 1F | E | KTUは存在しません |
9D | 20 | E | アプリケーションがロードされていません |
9D | 21 | E | オープンコマンドのデータ長が無効です |
9D | 30 | E | データパラメータが正しくないことを確認してください(開始アドレスが無効です) |
9D | 31 | E | データパラメータが正しくないことを確認してください(長さが無効です) |
9D | 32 | E | チェックデータパラメータが正しくありません(不正なメモリチェック領域) |
9D | 40 | E | 無効なMSMコントロール暗号文 |
9D | 41 | E | MSMコントロールはすでに設定されています |
9D | 42 | E | MSMコントロールのデータ長を2バイト未満に設定します |
9D | 43 | E | 無効なMSMコントロールのデータ長 |
9D | 44 | E | 過剰なMSMは暗号文を制御します |
9D | 45 | E | MSMコントロールデータの検証に失敗しました |
9D | 50 | E | MCD発行者のプロダクションIDが無効です |
9D | 51 | E | 無効なMCD発行者ID |
9D | 52 | E | 無効なセットMSMはデータ日付を制御します |
9D | 53 | E | 無効なMCD番号 |
9D | 54 | E | 予約フィールドエラー |
9D | 55 | E | 予約フィールドエラー |
9D | 56 | E | 予約フィールドエラー |
9D | 57 | E | 予約フィールドエラー |
9D | 60 | E | MAC検証に失敗しました |
9D | 61 | E | 到達したブロック解除の最大数 |
9D | 62 | E | カードはブロックされませんでした |
9D | 63 | E | 暗号機能は利用できません |
9D | 64 | E | アプリケーションがロードされていません |
9E | 00 | PINがインストールされていません | |
9E | 04 | PINが正常に検証されていない、PINがインストールされていない | |
9F | 00 | PINがブロックされ、ブロック解除試行カウンターが3 | |
9F | 04 | PINが正常に検証されず、PINがブロックされ、ブロック解除試行カウンターが3 | |
9F | XX | コマンドは正常に実行されました。'xx'バイトのデータが使用可能であり、GETRESPONSEを使用して要求できます。 | |
9X | XX | アプリケーション関連のステータス、(ISO 7816-3) |