マイナンバーカードのQRコードの(人力での)読み方

マイナンバーカードのQRコードを人力で読める人が多いとヤバいらしいので、人力で読むのがどの程度の難易度なのか試してみる。

このサイトにQRコードの作り方が載っているので、逆をやれば良い。

QRコードをつくってみる その1

「人力は面倒だけど、スマホのリーダーだと答えしか教えてくれないので、途中経過を知りたい」という場合には、このスクリプトが役に立つ。

waidotto/strong-qr-decoder: 強力なQRコードデコーダ

経緯

マイナンバーカードを身分証明書として使いたいけど、他人に見せるときにマイナンバーが見えてしまうと困るので、マイナンバーだけを隠すケースを国が配布した。ところが、マイナンバーカードにはマイナンバーがQRコードでも印字されていて、ケースはこのQRコードを隠さない。

国配布のケース、マイナンバーQRコード丸見え : 社会 : 読売新聞(YOMIURI ONLINE)

総務省曰く、

QR コードは、仮に目視しても記録されている情報がわかるものではなく、記録されているマイナンバーを不正に読み取るためには機器の使用が必要であり、このような行為は、カードケースを外そうとする行為と同程度に不自然であることが周囲から一目瞭然である

http://www.soumu.go.jp/main_content/000425732.pdf

「目で読める人がいっぱいいたらどうするの?」

QRコードの読み方

上記のサイトを見ると、QRコードを読むのはそうとう面倒に思えてくるが、作ることに比べるとかなり楽。複雑な数式が出てくる誤り訂正符号も考える必要が無い。誤り訂正符号は、元の符号の後ろに誤り訂正用の符号を追加するものなので、誤り無く読み取れるのならば、単に先頭を読むだけで良い。また、QRコードには英数字だけとか数字だけとかいくつかのモードがあるが、(おそらく)英数字モードしか使われていない。サイズが大きいと、データをいくつかに分けて混ぜ合わせるようなインタリーブ処理が必要になるけれど、小さいので不要。

私はマイナンバーカードを申請していないが、柏市のサイトに大きなマイナンバーカード裏面の画像があったので、これを読んでみる。

ペイントでドットを打って転写したのが↓のQRコード

f:id:kusano_k:20160626000213p:plain

この内、実際に読む必要があるのは、赤枠で囲った部分。左側の3画素と、右側の77画素。

f:id:kusano_k:20160626161254p:plain

例えば、0を多く含むようなデータを素直にQRコードにすると、全体が白くなってしまう。それでは読み取りに困るらしく、データを並べた後にルールに従って画素を反転するという処理がある。これに使われるマスクは8種類あって、どれを使ったかが左の3画素に書かれている。左から読んで、101とxorをする。このQRコードでは、000なのでxorをして101。5番目のマスクを使う。マスクの一覧は下の通り。青い画素はそのままで赤い画素を反転させる。マスク情報のところにはxorを取る前の画素を書いている。

f:id:kusano_k:20160626002853p:plain

5番のマスクでxorを掛けたQRコードは次のようになる。

f:id:kusano_k:20160626005059p:plain

この画像から01を読んでいく。読んでいく順番が分かりづらいが、右下から順に右左右左と2列で上に向かって読んでいく。上に達したら左にずれて同じく2列ずつ下に読んでいく。

f:id:kusano_k:20160626002721p:plain

マイナンバーのQRコードでは、数字を振った7個のコード語を読む。1個11bit。ちなみに、右下の4bitはモードを表わしていて、マイナンバーの場合は英数字なので常に0010になるはず。次の9bitはデータ長でマイナンバーの場合は14桁なので常に000001110。「マイナンバーは数字12桁では?」と疑問だったが、4桁ごとに空白が入って英数字14桁だった。

f:id:kusano_k:20160626005111p:plain

コード語は、

  • 00000101111
  • 00010001011
  • 11001011001
  • 00100010101
  • 00110001100
  • 00110010101
  • 00000101111

これを45で割って、商と余りに分ける。例えば最初の00000101111は47なので、商が1で余りが2。同様に他のコード語も計算していくと、

  • 1, 2
  • 3, 4
  • 36, 5
  • 6, 7
  • 8, 36
  • 9, 0
  • 1, 2

あとはこの数列を英数字に直すだけ。マイナンバーの場合は数字と空白のみなので簡単で、数字はそのまま、36を空白に直す。

1234 5678 9012

結論

これを暗算は無理でしょ……。スマホで盗撮するほうが楽。

マイナンバーは個人を識別するための番号で、今までだったらその役割は氏名と生年月日のペアなどだったと考えると、そこまで厳重に守る必要はあるのだろうか……。

追記

別にデコードまでする必要は無くて、単に白黒を覚えるだけで良いのかもしれない。

右下のあたりを塗りつぶせば……。捕まっても知りません。