マイナンバーカードでSSHする

Thu, Jun 23, 2016

みなさんマイナンバーカードはもう手元に届きましたか? 私の住む大田区はとても混雑していて申請から5ヶ月かかって今月やっと交付してもらうことができました。

このカードに含まれる公的個人認証機能は以前から住基カードに入っていたものですが、今年から民間利用もできるようになりました。

しかし、この公的個人認証ですが詳細な仕様が公開されていないため、商用利用しようという動きはまだ聞きませんし、既に動いている行政サービスのe-govやe-taxはIE限定で、いまだにJava Appletが使われているなど大変残念な状況です。

カードに入っている電子証明書と2048bitのRSA秘密鍵は様々な用途に活用できる可能性があるのに、せっかく税金を費やして作ったシステムが使われないのはもったいないですね。

民間利用の第一歩として、カードに入っているRSA鍵を利用して自宅サーバーにSSHログインしてみましょう!

MyNumber SSH

2種類の証明書

公的個人認証APには従来の住基カードに含まれていた署名用証明書に加え、新たに認証用証明書が格納されています。

署名用証明書は銀行口座の開設など、これまで免許証で本人確認していたビジネスシーンで名前や住所を証明する為に利用できます。

一方、認証用証明書はWebサイトなどにログインする用途で利用する事が想定されていますが、今回の様にSSHやPAM、PGP、Windowsログオン、無線LANの認証(WPA-EAP-TLS)で利用することもできるでしょう。

ほどんどの人が用途を見いだせなかった住基カードど違い、今回の個人番号カードは活用方法がたくさんありますね!

ちなみに公的個人認証APはマイナンバーを証明するためのものではありませんし、このAPにマイナンバーは含まれていません。 認証用証明書のCNは特に意味のないシリアル番号になっていて、署名用証明書のX509v3 Subject Alternative Nameには住所・氏名などの情報が入っています。

個人番号カードのファイルシステム

個人番号カードは以下の様なディレクトリ構造になっています。

個人番号カードのファイルシステム

署名プロトコル

公的個人認証APで署名を行うには、以下のような流れになります。

  1. 公的個人認証APにSELECT FILEする
  2. 認証用PIN IEFにSELECT FILEする
  3. VERIFYコマンドでPINを入力する
  4. 認証用秘密鍵IEFをSELECT FILEする
  5. 署名ファイルのハッシュ値をカードに送信し、レスポンスを受け取る

具体的にはカードに対して以下のようなデータを流し込みます。 (< 送信データ, > 受信データ)

個的個人認証APをSELECT FILEする
< 00 A4 04 0C 0A D3 92 F0 00 26 01 00 00 00 01
> 90 00
認証用PIN IEFをSELECT FILE
< 00 A4 02 0C 02 00 18
> 90 00
VERIFYコマンド(4桁の暗証番号をASCIIで)
< 00 20 00 80 04 XX XX XX XX
> 90 00
秘密鍵IEFをSELECT FILE
< 00 A4 02 0C 02 00 17
> 90 00
署名
< 80 2A 00 80 [PKCS1形式のハッシュ値]
> [署名データ]

OpenSCカードドライバ

カードとバイナリで会話するなんてなんだか大変そうだな。と思った方は安心してください。 個人番号カード用のOpenSCカードドライバをつくりました。

OpenSCはクロスプラットフォームで動作するスマートカード用のツール・ライブラリ群です。 カードドライバはカード固有の独自仕様を吸収し、標準仕様に適合させる役目を持ったミドルウェアです。

これは個人番号カード向けのPKCS#11 APIを実装し、PKCS#15エミュレーションできるようになったことを意味します。まだまだ完全ではありませんがSSH出来る程度には完成したという事です。

ソースコードはこちら1です。現在OpenSCプロジェクト本体にマージする作業を行っています2がひとまずこちらのレポジトリのjpkiブランチをcloneしてください。

$ git clone https://github.com/jpki/OpenSC.git
$ ./bootstrap
$ ./configure --enable-openssl
$ make
$ make install

追記: openssl開発環境が無いと pkcs15-tool の –read-ssh-key オプションが消えるっぽい

SSHする

カードリーダーはWindws/Mac/Linuxで使えることを確認済みのこちらのNFCリーダーがオススメです。

ADVANCED CARD SYSTEM ACR1251U-A9 NFCカードリーダー

まずは認証用公開鍵をOpenSSH形式で取り出して、authorized_keysに登録しましょう。

$ pkcs15-tool --read-ssh-key 1 > id_rsa.pub

公開鍵をサーバーに登録したら、いよいよSSHログインです。

OpenSSHはPKCS#11 APIに対応していますので-IオプションでさきほどビルドしたPKCS11ライブラリを指定します。 (~/.ssh/configにPKCS11Provideを指定できるので通常この長いオプションは不要です。)

$ ssh -I /usr/local/lib/opensc-pkcs11.so hostname
Enter PIN for 'JPKI (User Authentication PIN)':

このようにPIN入力を求められるので役所で設定した4桁数字の暗証番号を入力します。 そうするとSSHサーバーから送られてきたNONCEにカード内の秘密鍵で署名して送り返して認証完了です!

今回はSSH認証なので証明書は使いませんでしたが、証明書の失効情報を得るにはなぜか総務大臣の認可が必要だそうなので証明書の検証が必要な場合は面倒ですが申請するしかないですね。

パスワード認証という苦行

みなさん普段利用しているパスワードは十分長く、ランダムかつサイト・サービス毎に異なるパスワードを設定していますか? はい、そんな事はほとんど不可能です。複数のランダムな文字列を人間の脳に記録するのは無理なので、ツールを使うしかありません。

パスワードレスなインターネット社会を作るにはPKIがひとつの解決方法ですがなかなか普及しません。 SSLクライアント認証を利用したWEBサービスがどれほどあるでしょうか? ITエンジニアが日常的に利用している非対称鍵認証はなぜ一般に利用されないのでしょうか?

障害の大部分は認証局の運用コストと鍵のポータビリティにあるのでしょう。 証明書を正しく発行し、失効情報を管理するにはそれなりのコストがかかります。 秘密鍵をカード内で生成し、取り出せないデバイスはまだ高価です。

今回この認証局の運用を国がやってくれて、国民一人一人に証明書と秘密鍵を配布してくれるというのですから、うまく行けばパスワードレスな社会の後押しになるかもしれません。

公的個人認証にはまだいろいろ制限がありますが、はやく人間がパスワードを憶えなくて良い世の中になると良いですね。

総務省へ

ここで個人番号カードの仕様を一部公開した目的は安全性を脅かすためではなく、むしろその逆で安全性の向上と公的個人認証の普及促進を目的としています。

一般的にプロトコル仕様の隠匿は安全性の向上に寄与しませんし、個人番号カードの相互運用性を著しく阻害するでしょう。

見習うべきはエストニアやベルギーの国民IDカードです。これらのカード仕様の詳細は完全に開示され、関連ツールのソースコードはgithubで公開3されています。 多くの人々の目に晒された上で安全性が維持されているのです。

国民IDカードの普及率と仕様のオープン性は無関係ではありません。事実エストニアの国民IDカードは高い普及率と利用率を達成しています。4

本当に個人番号カードを普及させたいのなら、APDU仕様とOCSPレスポンダを公開したほうがよいでしょう。

参考資料