Rustでマイナンバーカードを操作するAndroidアプリを作る
マイナンバーカードでデジタル署名ができることを知り、池口氏は作ってみたいスマホアプリの着想を得た。シンプルなAndroidアプリで、署名したいメッセージと利用者証明用鍵の暗証番号を入力し、マイナンバーカードをスマホにかざして署名したり、署名を確認したりできるというものだ。池口氏は「せっかくなら流行の技術を採り入れたい。このイベントはU30であることからも 、若い技術を使いたい。そこでRustを使うことにしました」と言う。
ちなみに今回のアプリ開発はゆめみの10%ルールにて行った。同社では業務時間の10%を研究開発やOSS貢献に利用していいという制度になっている(2022年1月現在、Rustについてはさらに拡張され20%ルールの対象となった)。池口氏は「正社員としてフルタイムで働きつつ、副業もしているので、なかなか時間がないという状況です。でもゆめみなら10%ルールがあるので気軽にこのようなことができるのです」と話す。10%ルールは複数のメンバーで取り組むことも可能だ。
今回は言語としてRustを選択したものの、Androidアプリでは基本的にJavaやKotlinを使うことが多い。そのためRustを機械語にコンパイルした上で、FFI(Foreign Function Interface)を用いて外部から呼び出す必要があった。
一方、マイナンバーカードとの通信にはAPDU(Application Protocol Data Unit)プロトコル[※3]を使うことができる。Android NDKがあってもRustのライブラリから直接デバイスのNFC通信にアクセスできないため委譲する形でAndroidアプリから処理する。
[※3] 財団法人ニューメディア開発協会(1998)『ISO/IEC 10536 準拠非接触 IC カード 実装規約書』。
FFIでの初期化時に、特定の関数ポインタをRustライブラリへ渡しておく。例えばRustライブラリで「署名してください」と命令を送った時に、「このAPDUコマンドを送信してください」という処理がAndroidアプリに返る。そしてAndroidアプリからNFCのAPIを用いて、コマンドを送信することで返ってきたものを送信し、再びRustライブラリに返すという流れになる。
「こうすることで、とても柔軟にRustライブラリを使い回すことができて、他環境にも対応できます。モバイルではiOS、ひいてはWindows、macOS、Linuxなどのパソコン環境にも対応できるのがいいところです」(池口氏)
実装については時間の都合でポイントのみの紹介に留めたが、GitHubに全て公開されているので詳しくは下記を参照してほしい。jpki-rsはコアの実装部分となり、マイナンバーカードのJPKIで署名する時のコマンドや処理がRustで記述されている。easy-jpkiはアプリのUIと署名の命令をライブラリ側へ送るところをKotlinで記述している。
- siketyan/jpki-rs:コアのRust実装部分とAndroidとのアダプタ部分
- siketyan/easy-jpki:AndroidアプリとしてのKotlin実装部分
実際にポイントとなるコードを見てみよう。NFCカードとの接続やUIを省くと、下記のものとなる。ここが「こういうコマンドを送って」と委譲された部分の処理となる。4行目の「isoDep.・・・」で、コマンドをマイナンバーカードへ送る流れとなる。
デジタル署名するボタンを押した時の処理は下記となる。1行目で現在のNFC通信をもとにライブラリの初期化処理を行い、2行目でデジタル署名する。ここでは暗証番号と署名するメッセージをバイト列で渡す。池口氏が「Rustのライブラリへ切り出すことによって、これだけで済ますことができる」と言う通り、確かにとてもシンプルだ。
マイナンバーカードが持つ技術的な意義とは?
実際のアプリの動きを池口氏は披露した。アプリを開いて暗証番号とメッセージを入力し「Sign」ボタンを押すと、まず署名の出力先となるファイルを選択する画面が表示される。ここでファイルを選択するとカード待機画面となり、ユーザーは端末にマイナンバーカードをかざす。端末がカードを読み取ると、署名が行われる。
次は署名を検証する機能を試す。今度はメッセージのみを入力して「Verify」ボタンを押し、検証したい署名を選択すると、先ほど同様にカード待機画面となり、ユーザーは端末にマイナンバーカードをかざす。カードが読み取られ、検証処理が走り、その結果が表示される。
最後に池口氏はこのアプリの意義について説明した。マイナンバーカードは健康保険証や運転免許証の代替として使えることがメリットとしてうたわれているが、そこは大して重要ではないと池口氏は考えている。「マイナンバーカードを作る最大のメリットは日本の公的な公開鍵基盤が発行した証明書が手に入ることなのです」(池口氏)
鍵そのものはいくらでも発行可能だ。ただしそれが実在する人物に紐付けられた鍵かどうかは分からない。しかしマイナンバーカードについては公的機関が鍵を発行しているため、ユーザーの公的な情報と紐付けられた鍵となる。
「マイナンバーの通知カードの状態ではNFCの機能は使えませんし、証明書も入っていない状態です。まだ通知カードだけでマイナンバーカードを作っていない人はマイナンバーカードを作って自分の公的な証明書を手に入れていただければと思います」(池口氏)
最後にRust言語に関しては「あまりコードを出せなかったものの、柔軟な言語なのでいろんなことに活用されると期待しています」と評価した。