内部認証
ICカード(マイナンバーカード等)から読み出したデータが、本物のカード由来であることを暗号学的に証明する仕組み。カード内の秘密鍵を用いた署名により、偽造カードを検知する。
概要
マイナンバーカードの券面APから顔写真や基本4情報を読み取る際、そのデータが本物のマイナンバーカードから読み出されたものであることを確認する必要がある。内部認証は、J-LISの公開鍵で検証可能な署名を用いて、カードの真正性を保証する。
技術的仕組み
1. 認証フロー
1. リーダー(アプリ)がランダムなチャレンジ(nonce)を生成
↓
2. マイナンバーカードがチャレンジを秘密鍵で署名
↓
3. リーダーがカード内の証明書(公開鍵)を取得
↓
4. リーダーが署名を公開鍵で検証
↓
5. リーダーが証明書をJ-LISのルートCA証明書で検証
↓
6. 両方の検証が成功 → カードは本物
2. PKI構造
J-LIS(ルート認証局)
├─ ルートCA証明書(公開鍵)
└─ 各マイナンバーカードの証明書に署名
マイナンバーカード(ICチップ)
├─ 内部認証用秘密鍵(外部に出ない)
├─ 内部認証用証明書(公開鍵+J-LISの署名)
└─ 券面データ(顔写真、基本4情報)
リーダー(検証側)
├─ J-LISのルートCA証明書(事前インストール)
└─ 署名検証ライブラリ
内部認証が防ぐ脅威
偽造カード攻撃
攻撃者が独自のICカードに顔写真と基本4情報を書き込んでも、内部認証用の秘密鍵を持たないため、署名検証に失敗する。
偽造カード
├─ 本人の顔写真(コピー)
├─ 本人の基本4情報(コピー)
└─ 内部認証用秘密鍵 ← なし(J-LISしか生成できない)
↓
署名検証失敗 → 偽造検知
データ改ざん攻撃
通信経路でデータを改ざんしても、署名検証に失敗する。
正規のカード → データ読出
↓
中間者がデータを改ざん
↓
署名とデータが不一致
↓
改ざん検知
eKYCでの利用
ヘ方式(マイナンバーカード)
1. ユーザーがスマホでマイナンバーカードをNFC読取
2. 照合番号Bで券面AP(顔写真)にアクセス
3. アプリがチャレンジ生成
4. カードが秘密鍵でチャレンジに署名
5. アプリが署名を検証(内部認証)
6. 検証成功 → カードは本物
7. 顔写真とユーザーの自撮りを[[顔認証]]で照合
8. 本人確認完了
ワ方式(公的個人認証)
ワ方式ではJPKIの署名用電子証明書を用いるため、内部認証とは異なるが、同様に証明書チェーン検証が行われる。
1. ユーザーが署名用PINを入力
2. カードが署名用秘密鍵でデータに電子署名
3. 事業者が署名用電子証明書を取得
4. 事業者が署名を検証
5. 事業者が証明書をJ-LISのルートCAで検証
6. 検証成功 → 本人確認完了
内部認証と公的個人認証の違い
| 観点 | 内部認証 | 公的個人認証 |
|---|---|---|
| 目的 | カードの真正性確認 | 本人の意思表示 |
| 使用する鍵 | 内部認証用秘密鍵 | 署名用秘密鍵 |
| PIN | 不要(照合番号Bのみ) | 必要(署名用PIN) |
| 証明するもの | カードが本物 | 本人の意思 |
| 法的効力 | なし | 電子署名法で実印相当 |
| 利用シーン | 券面データ読取(ヘ方式) | 電子署名(ワ方式) |
技術的詳細
証明書フォーマット
X.509証明書形式。
証明書
├─ バージョン: v3
├─ シリアル番号: (カード固有)
├─ 署名アルゴリズム: SHA256withRSA / ECDSA
├─ 発行者: J-LIS
├─ 有効期限: カードの有効期限まで
├─ 主体: (カード識別情報)
├─ 公開鍵: RSA 2048bit / ECC P-256
└─ J-LISの署名
署名アルゴリズム
- RSA: 2048bit以上
- ECDSA: P-256カーブ(secp256r1)
チャレンジ・レスポンス
Challenge(8〜32バイトのランダム値)
↓
カード内で秘密鍵を使ってChallenge+αに署名
↓
Response(署名値)
↓
リーダーが公開鍵で検証
セキュリティ特性
秘密鍵の非抽出性
内部認証用秘密鍵はICチップ内で生成され、外部に出ない。物理的解析にも耐える設計(耐タンパー性)。
リプレイ攻撃耐性
チャレンジが毎回ランダムに生成されるため、過去の署名を再利用できない。
中間者攻撃耐性
署名にはチャレンジが含まれるため、通信を盗聴・改ざんしても無効。
実装上の注意点
J-LISのルートCA証明書
リーダー側アプリに事前にJ-LISのルートCA証明書を組み込む必要がある。
ルートCA証明書の取得
├─ J-LIS公式サイトからダウンロード
├─ アプリに埋め込み(ハードコード or 証明書ストア)
└─ 定期的な更新(有効期限に注意)
証明書失効リスト(CRL)
カードが失効(紛失・盗難等)した場合、CRLで確認する。
オンライン時
↓
J-LISのCRL/OCSPで失効確認
↓
失効済み → カード無効
オフライン対応
内部認証自体はオフラインで実行可能だが、CRL確認はオンラインが必要。厳密な運用ではオンライン確認が推奨される。
実装例(疑似コード)
import cryptography
# 1. チャレンジ生成
challenge = os.urandom(16)
# 2. カードに送信し、署名を取得
signature = card.internal_authenticate(challenge)
# 3. カードから証明書を取得
certificate = card.read_certificate()
# 4. 署名を検証
public_key = certificate.public_key()
try:
public_key.verify(signature, challenge, ...)
print("署名検証OK")
except InvalidSignature:
print("署名検証NG - 偽造カード")
return False
# 5. 証明書チェーン検証
root_ca = load_jlis_root_ca()
try:
verify_certificate_chain(certificate, root_ca)
print("証明書検証OK")
except InvalidCertificate:
print("証明書検証NG - 不正なカード")
return False
# 6. 両方成功 → カードは本物
print("内部認証成功 - カードは本物")
return True
今後の展望
スマホ搭載マイナンバーカード
物理カード不要で、スマホ内のSE(Secure Element)に秘密鍵を格納。
スマホのSE
├─ 内部認証用秘密鍵
├─ 署名用秘密鍵(JPKI)
└─ 券面データ
↓
同じ内部認証の仕組みを適用
ゼロ知識証明(Zero-Knowledge Proof)
基本4情報を明かさずに、「マイナンバーカード保有者である」ことのみを証明する技術。
zkSNARK等の暗号技術
↓
「J-LISが発行したカードを持っている」
↓
個人情報は開示しない