💳

マイナンバーカードから基本4情報の取得

2024/12/21に公開

マイナンバーカードをスマホから基本4情報(名前、住所、生年月日、性別)読み取る方法について
マイナンバーカードはAPDUでやり取りを行います。

APDU(Application Protocol Data Unit)とは

APDUコマンドはICカードとデバイス(スマホ・読み取り機器など)が通信する標準プロトコル
ざっくりいうとAPDUコマンドはICカードに対して命令を送るためのデータ形式

APDUは命令コマンドやレスポンスのフォーマットが決まっています。
形式に沿った方法でないと正常に動作しません。

APDUコマンドの構造

送信時の形式

+------+----+----+----+-----+-----------+------+
| CLA  | INS| P1 | P2 | Lc  | Data ...  |  Le  |
+------+----+----+----+-----+-----------+------+

・CLA (1バイト): コマンドのクラス(プロトコルやセキュリティレベルを指定)
・INS (1バイト): コマンドの種類(例: SELECT, READ, WRITE など)
・P1 (1バイト): コマンドに関するパラメータ1
・P2 (1バイト): コマンドに関するパラメータ2
・Lc (1 or 3バイト): 送信するデータの長さ(オプション)
・Data: コマンドに付随するデータ(例: PINなど)
・Le (1 or 3バイト): カードからのレスポンスデータの要求長さ(オプション)

Lc以降はオプションです。
Dataでマイナンバーのパスワードを送る場合、
LcとDataが必要になります。
Dataがない場合はLcとDataは省略します。
LcとDataがなくLeだけの場合もあります。

レスポンス形式

+-----------+-----+-----+
| Data ...  | SW1 | SW2 |
+-----------+-----+-----+

・Data: 応答データ(読み取ったファイル内容など)
・SW1, SW2: ステータスワード(レスポンスコード)

レスポンスコードは
90 00が成功です。

主なコマンド

通信時に使用するコマンドは決まっています。
主なコマンドは下記です。

SELECT
アプリケーションやファイルを選択するためのコマンド

VERIFY
PIN(暗証番号)の検証を行うコマンド

READ BINARY
ファイルを読み出すためのコマンド

ICカードの構造

MF
├─ DF
└─ DF
   └─ EF 

MF: マスターファイル。カードのルートにあたる。
DF: Dedicated File 専用ファイル。
EF: Elementary File 基礎ファイル。実際の個人情報

ICカードの構造は上記のようになっており、全てファイルですが、MF、DFはディレクトリと同じものと認識してます。

マイナンバーの場合

MF
├─ DF: 券面補助入力AP
  ├─ EF: 基本4情報等のデータ 
  └─ EF: 入力補助用PIN
└─ DF: 公的個人認証AP
  └─ EF: 利用者証明用・署名用の証明書、鍵、署名機能など

マイナンバーの場合上記のような感じになってます。
ここからAPDUコマンドを使用して、どのディレクトリのデータを取得するか入力します。

ぞれぞれ取得するディレクトリ名は下記になります。
公的個人認証AP: D3 92 F0 00 26 01 00 00 00 01
券面補助入力AP: D3 92 10 00 31 00 01 01 04 08

基本4情報取得

基本4情報の取得にはコマンドを順番に組み合わせて使用します。
また取得時には4桁のパスワードが必要になります。

ざっくり流れは
SELECT→SELECT→VERIFY→SELECT→READ BINARY→READ BINARY
の順番でコマンドを使用していきます。

マイナンバーの基本4情報を取得するには「券面入力補助AP」を指定してあげます。

# SELECT: 券面入力補助AP (DF)
00 A4 04 0C 0A D3 92 10 00 31 00 01 01 04 08

CLA: 00
INS: A4 SELECTコマンドを表す。
P1: 04 SELECTコマンドのP1は、選択方法を表す。04は「DF名(AID)による選択」
P2: 0C SELECTコマンドのP2は、レスポンスデータのフォーマットやオプションを指定
Lc: 0A データフィールドのバイト数。今回は10バイト
data: D3 92 10 00 31 00 01 01 04 08 券面補助入力APを選択

AIDによって券面入力補助APを選択してください。
というコマンドを送ってます。

# SELECT: 入力補助用PIN (EF)
00 A4 02 0C 02 00 11

CLA: 00
INS: A4 SELECTコマンドを表す。
P1: 02 AID選択とは異なり、既に選択済みのDF内から特定のEFをファイルIDで指定する。
P2: 0C フォーマット指定
Lc: 02 データフィールドのバイト数。今回は2バイト
data: 00 11 EFのファイルID。入力補助用PINのID=0011

すでに選択されている券面入力補助APの中から、「ファイルID=0011」のEF(ここでは「入力補助用PIN」が格納されているEF)を選択してください
と送っています。

# VERIFY: 入力補助用PIN (パスワード=1234)
00 20 00 80 04 31 32 33 34

CLA: 00
INS: 20 VERIFYコマンドを表す。
P1, P2: 00 80 対象PINや検証方法がカード仕様で定義されてる
Lc: 04 データフィールドのバイト数。今回は4バイト
data: 31 32 33 34 パスワード

入力補助用PINのEFが選択されている状態で、「1234」というPINをカードへ送り正しいか検証している。

# SELECT FILE: 基本4情報 (EF)
00 A4 02 0C 02 00 02

CLA: 00
INS: A4 SELECTコマンドを表す。
P1: 02 AID選択とは異なり、既に選択済みのDF内から特定のEFをファイルIDで指定する。
P2: 0C フォーマット指定
Lc: 02 データフィールドのバイト数。今回は2バイト
data: 00 02 EFのファイルID。基本4情報のID=0002

すでに選択されている券面入力補助APの中から、「ファイルID=0002」のEF(ここでは「基本4情報」が格納されているEF)を選択してください
と送っています。
マイナンバー(個人番号)のIDは0001です。
こちらも取得可能です。

READ BINARY: 基本4情報の読み取り(3バイト目のデータ長のみ)
00 B0 00 02 01

CLA: 00
INS: B0 READ BINARYコマンドを表す。
P1, P2: 00 02 オフセット。2バイト目から読み込み開始
Lc: なし
Le:01 1バイト要求

現在選択中のEF(基本4情報が格納されているファイル)のオフセット2(=3バイト目)から1バイトだけ読み込む処理です。
基本4情報のデータ長は可変です。
3バイト目にデータ全体の長さ情報が格納されています。
これで取得すべきデータ長がわかります。

READ BINARY: 基本4情報の読み取り
00 B0 00 00 70

CLA: 00
INS: B0 READ BINARYコマンドを表す。
P1, P2: 00 00 オフセット。先頭から読み込み開始
Lc: なし
Le:70 112バイト要求

先ほどのデータ長の戻りに応じてLeの値を変更する。
取得したデータはUTF8でエンコードされているので、デコードすることで正しい値を取得することができます。

まとめ

マイナンバーカードから基本4情報を取得する一連の流れです。
実際の取得する必要があったので調べた内容のまとめです。
Suicaも同じで読み取ることできるらしい。。
知らんけど。

参考
https://www.soumu.go.jp/kojinbango_card/03.html
https://tex2e.github.io/blog/protocol/jpki-mynumbercard-with-apdu
https://speakerdeck.com/tex2e/secminicamp2023-mynumber?slide=62
https://cardwerk.com/smart-card-standard-iso7816-4-section-6-basic-interindustry-commands/

Discussion