マイナンバーカードに スマホだけで 署名させる — 自作Androidアプリでリーダー問題を超える

これまでの記事で、マイナンバーカードを Safari の WebAuthn 認証器にしGoogle でも使えるようにしました。ただ実用には大きな壁が一つ残っていました——カードの読み取りに USB カードリーダーが要ること。会社で全員に使ってもらうのに「各自リーダーを買って」は現実的ではありません。今回はこの「読み取りハード問題」を、スマホの NFC で超えられるか実機で検証しました。

答えは「スマホ」。しかも前例がある

マイナンバーカードは NFC カードです。そしてほぼ全員が NFC 付きスマホを持っている。実際、デジタル庁の「デジタル認証アプリ」も、スマホの NFC でカードを読んでいます。つまり専用リーダーは要らない——理屈ではそうですが、「自分で作った third-party アプリが、マイナの利用者証明用鍵で署名できるのか?」が分かれ目でした。ここが通らないと、スマホを自前の認証器にする構想は成立しません。

Android で最小実装

Android は IsoDep で ISO7816 の APDU を自由に投げられます(third-party に開放)。カードに送るコマンドは、デスクトップ版(jpki/myna)と同じ 5 つだけ:

1. SELECT AP : 00 A4 04 0C 0A D3 92 F0 00 26 01 00 00 00 01  (JPKI AP)
2. SELECT EF : 00 A4 02 0C 02 00 18                          (利用者証明用PIN)
3. VERIFY    : 00 20 00 80 <len> <PIN(ASCII)>                 (残回数は 00 20 00 80 → 63Cx)
4. SELECT EF : 00 A4 02 0C 02 00 17                          (利用者証明用 秘密鍵)
5. SIGN      : 80 2A 00 80 <len> <DigestInfo> 00            (RSA署名 256B)

Kotlin では NFC リーダーモードでタグを掴み、isoDep.transceive() でこの 5 コマンドを順に送るだけ。Compose も外部ライブラリも不要の最小アプリです。

⚠️ 安全策:PIN は3回ミスでロック

利用者証明用パスワードは3回間違えるとロックします。検証アプリでは事故防止に、

  • 署名前に残回数をチェック(データ無しの VERIFY → 63 Cx の x が残り回数)
  • 残回数が3未満なら自動で中止(うっかり連続ミスでのロックを防ぐ)
  • VERIFY は1回だけ、失敗したら即停止

自前でマイナの PIN を扱うなら、この残回数ガードはほぼ必須だと思います。

結果:スマホだけでマイナに署名できた

実機(Pixel)で、PIN を入れてカードを背面にかざすと:

PIN残回数: 3
✅ VERIFY 成功
✅ SIGN 成功! RSA署名 256 bytes
seed = SHA256(署名) = 41E9F2AA1DAFBF75…

自作の third-party アプリが、専用リーダー無しで、マイナの利用者証明用鍵による署名を取得できました。この RSA 署名を種(seed)にして、サイトごとの鍵(Ed25519 / ES256)を導出する——という、これまで作ってきた仕組みにそのまま繋がります。

これで何ができるか

  • 読み取りハード問題の解消:全員が持つスマホの NFC でカードを読む。専用リーダー不要。
  • スマホを認証器に:スマホで鍵導出・署名し、PC ブラウザの WebAuthn へは自前のリレー(QR + 暗号化チャネル)で渡す構成が見えてくる(標準の「スマホを使う」= caBLE は third-party に開かれていないため、ここは自作する)。
  • 企業の機密文書管理:たとえば Google Drive の機密フォルダを開く時だけマイナをかざす——を、追加ハード無しで狙える。
  • 将来はスマホ用電子証明書(SE 搭載)で、カードのタップすら不要に。

正直な限界

この方式はカードを「種の供給源」として使い、鍵の導出・署名はソフト側で行います(WebAuthn 用の鍵はカード内の鍵そのものではない)。そのため鍵の耐タンパー性は専用セキュリティキー(YubiKey 等)には及びません。位置づけは「金庫」ではなく「全員が持つカードで、所持 + PIN による本人性とフィッシング耐性を低コストで足す層」。重要操作はさらに OIDC(デジタル認証アプリ)で本人性を再確認する、という多層で補います。

次は、このスマホ署名からサイト別鍵の導出PC ブラウザへのリレーを実装して、「リーダーレスでの WebAuthn 認証」を通すところまで進めます。

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

IP: 取得中...
216.73.217.46216.73.217.46