認証を行うには、AuthenticateEVFirst というコマンドを投げます。AN12196 の 6.6 の手順になります。(以下、資料内のデータをそのまま記載します)
CLA | 90 |
INS | 71 |
P1 | 00 |
P2 | 00 |
Lc | 02 |
Data | 0000 |
Le | 00 |
Dataの1バイト目は使用する Key の番号で 0 を指定しています。すると応答が来ます。
A04C124213C186F22399D33AC2A3021591AF
最後の2バイト(91AF)は応答コードで、AFはコマンドに続きがあることを示します。先頭から16バイトが、タグ側で生成された乱数(16バイト、資料ではRndBと記載)を Key0 で暗号化した値になります。暗号は AES128-CBC(パディング無し)が使用されます。Keyはタグ側で保持している Key0 の値を使用し、IV はオール0(16バイト)が使用されます。
そういうわけで、これを復号するにはタグに保持されている Key0 を知っている必要があります。デフォルトではオール0になっているので、Key=オール0、IV=オール0で復号します。
RndB = B9E2FC789B64BF237CCCAA20EC7E6E48
これでタグ側で生成された乱数が取得できました。
続いてリーダ側で乱数を生成し(RndA)、タグに送ります。
RndA = 13C5DB8A5930439FC3DEF9A4C675360F (乱数なのでなんでもいい)
そのままこの値を送信するのではなく、タグに送信するデータを組み立てます。
RndBを1バイト左にローテーションします。
RndB' = E2FC789B64BF237CCCAA20EC7E6E48B9
RndA と RndB' をくっつけます。
RndA || RndB' = 13C5DB8A5930439FC3DEF9A4C675360FE2FC789B64BF237CCCAA20EC7E6E48B9
先ほどと同じ Key=オール0、IV=オール0で暗号化します。
35C3E05A752E0144BAC0DE51C1F22C56B34408A23D8AEA266CAB947EA8E0118D
これをDataとしてAPDUコマンドを送ります。
CLA | 90 |
INS | AF |
P1 | 00 |
P2 | 00 |
Lc | 20 |
Data | 上記の値 |
Le | 00 |
レスポンス
3FA64DB5446D1F34CD6EA311167F5E4985B89690C04A05F17FA7AB2F081206639100
最後の2バイト(9100)は正常応答のコードです。
先頭32バイトを復号します。
9D00C4DFC5DB8A5930439FC3DEF9A4C675360F13000000000000000000000000
先頭から、TI(トランザクション識別子)、RndA'、PDcap2、PCDcap2の値になります。
TI = 9D00C4DF
RndA' = C5DB8A5930439FC3DEF9A4C675360F13
RndA'は、RndAを1バイト左にローテーションした値になっています。これで正常に乱数がやり取りできたことを示します。
PDcap2とPCDcap2の値は使用しません。
ここからこの先のコマンドをやり取りするときに利用する暗号キーを組み立てます。
SV1 = A55A00010080 [RndAの先頭2バイト] [RndAの3バイト目から6バイトとRndBの先頭から6バイトをそれぞれ XOR したもの] [RndBの7バイト目から16バイト目まで] [RndAの9バイト目から16バイト目まで]
=A55A0001008013C56268A548D8FBBF237CCCAA20EC7E6E48C3DEF9A4C675360F
SV2 = SV1 の先頭2バイトを 5AA5 に変更
=5AA50001008013C56268A548D8FBBF237CCCAA20EC7E6E48C3DEF9A4C675360F
次にSV1とSV2を使って、上記の暗号とは少し違う AES-CMAC という方式で Key0 を使って認証値(ハッシュ値的な?)を計算します。
Encryption Session Key = CMAC(k0, SV1)
= 1309C877509E5A215007FF0ED19CA564
CMAC Session Key = CMAC(k0, SV2) = 4C6626F5E72EA694202139295C7A7FC7
これで認証の作業は終了です。次はいよいよ設定値の変更になります。
0 件のコメント:
コメントを投稿