――
コロナ・ワクチンの認証方式について、「接種券番号を 23桁にするべきだ」と高木浩光氏が述べている。
まずは、これ。
出鱈目B「現行法では架空予約は防げない」とあるが、摂取券番号をランダム20桁ほどのスパースな番号で発行して管理すれば(発行済みの番号かチェックするだけ)防げる。(QRコードを用いたシステムなどでごく一般的な方法。他に、HMACを使う方法などもある。) pic.twitter.com/F4LkUAS6YY
— Hiromitsu Takagi (@HiromitsuTakagi) May 19, 2021
さらに、朝日新聞でも述べた。(有料会員限定)
5回間違ったらロックする、といった仕組みにしたとしても、接種券番号の方を変えながら攻撃されるとロックできず、数千個に1個程度の番号で、当たってしまいます。つまり、この方法では結局、完全には防げないわけです。
――マイナンバーを使えば対策になりますか。
マイナンバーでは解決しません。12桁しかありませんので、いまの接種券番号が10桁なのとほとんど変わらず、同じ原理で当てられてしまいます。
――どうすべきだったのでしょうか。
接種券番号と生年月日で登録する方式でいくなら、接種券番号をランダムな23桁ほどの数字にすることで完全に解決できます。そうすれば、数字の組み合わせは膨大になります。そのなかに本物の番号がごくまれに入っているようにして、システム側で本物の番号かチェックするわけです。
これなら悪意を持った人がランダムに接種券番号を入力しても、本物の番号と一致する確率は無視できるほどに小さくなります。こういう仕組みは、ネットで使えるギフト券のギフト券番号でも使われています。
( → ワクチン予約サイト、プロが示す「最悪シナリオ」対処法 :朝日新聞 )
有料会員向けの記事を大きく引用することには倫理的な問題があるが、間違った情報がおおっぴらに公開されていることには社会的な害悪があるので、ここで指摘する。
(1) 10+12 ≒ 23
「マイナンバーでは解決しません」というが、「接種券ナンバーとマイナンバーの併用」ならば、 10桁 プラス 12桁 で、合計 22桁になる。これならば、攻撃に対する強度は、23桁の場合とほとんど違いはない。
だから、「接種券ナンバー単独」(10桁)や、「マイナンバー単独」(12桁)では駄目だとしても、「接種券ナンバーとマイナンバーの併用」ならば、23桁の場合とほとんど同様の強度を保てるのだ。
(2) 23桁は不要
23桁の数字を提案しているが、これでは数字が多くなりすぎる。利用者の負担が大きくなりすぎる。人間は、10桁ぐらいならば容易に照合できるが、23桁も照合するのは、とても負担が大きい。
接種会場の場などでも、番号の照合に時間がかかって、作業能率が大幅に低下してしまうだろう。下手をすると、接種可能人数が低下するせいで、ワクチンの未接種者が大幅に増えてしまう。……これでは本末転倒だ。
そもそも、ワクチンの予約には、厳重な管理などは必要ない。高木浩光氏は、「こういう仕組みは、ネットで使えるギフト券のギフト券番号でも使われています」というが、それは「ネットで金銭を奪う」という大きな金銭的利得がある場合だから、厳重な管理が必要になるからだ。
一方、ワクチンの予約では、他人ができるのは、せいぜい、「代わりに予約番号を取って、本人が取るのを邪魔すること」だけだ。つまり、ただの悪戯だけだ。金銭的な利得などはない。こういう場合には、やたらと厳重な管理は必要ないのだ。
(3) 4桁でも足りる
さらに言えば、ワクチン予約の場合には、本人が接種券をもっていないと、接種してもらえない。これは、「銀行の ATM は、キャッシュカードをもっていないと使えない」というのと同様だ。接種券であれ、キャッシュカードであれ、物理的な「キー」となるものが必要だ。それなしには他人は侵入できないのだ。こういう場合には、厳重な管理は必要ない。
銀行のキャッシュカードは、たった4桁の暗証番号があるだけだ。それでも、「銀行の ATM は、キャッシュカードをもっていないと使えない」という制限があるから、4桁でも足りる。
ワクチンの接種の予約も同様だ。「接種券をもっていないと使えない」という制限があるから、暗証番号は4桁でも足りる。
(4) ハッシュ値
では、その4桁は、どうやって得るか? 「ハッシュ値を使えばいい」というのが、私の提案だ。
→ ワクチン接種予約システムの欠陥: Open ブログ
私がこれを書いたのが 2021年05月17日。以後、ネット上では、同様に「ハッシュ値を使えばいい」という提案があふれた。 twitter でも、そういう意見が多数見つかる。
このような場合の「検証用の数値」には、「ハッシュ値を使う」というのが、コンピュータについては常道なのだ。ふだんプログラムを書いているような人なら、すぐに思いつくことだろう。(私の独創ではない。)
なのに、普通の人ならばすぐに思いつくことを提唱しないで、「23桁の番号」なんていう巨大なものを持ち出すのは、いかにも不思議である。「牛刀をもって鶏を割く」という感じだ。
たとえれば、初歩的な因数分解の証明をするのに、高度な微積分や複素解析を用いるようなものだ。無駄な高度な力をやたらと注入するのは、数学的センスがないと言える。
別の比喩で言えば、20メートル先のコンビニに行くのに、ランボルギーニで 600馬力のエンジンを動かすようなものだ。そんなデカいものを使うと、始動のアイドリングをするだけでも、多大な手間となって、歩くよりもかえって遅くなってしまう。壮大な無駄だ。
――
ともあれ、結論としては、次のように言える。
・ 23桁の数字を使うのは、桁が多すぎて不便なので、不可。
・ 接種券番号に4桁のハッシュ値を付けるのが、最善。
・ それをしないのなら、事後的に、12桁のマイナンバーで検証する。
※ 手法は → 接種予約システムを改修: Open ブログ
・ 現状では、生年月日を仮のパスワードとするが、それでは不十分である。
※ この点は、高木浩光氏の指摘通り。
【 追記 】
どうしても多大な攻撃に対する対処を必要とするので 23桁にするのなら、10桁の接種券番号に対して、ハッシュ値を 13桁にすればいい。そうすれば、ネット上の攻撃に対しては、23桁で対処できる。一方、接種会場では、(現物の接種券がある限り)ハッシュ値は必要としないので、10桁の数値だけで足りる。
ハッシュ値という概念さえ知っておけば、こういうふうに効率的な運用ができるのだ。高木浩光氏は、そういう発想がないようだ。(プログラムを書く人ならば、ハッシュ値という概念ぐらいはわかっているものだが。)
【 追記2 】
高木浩光氏には、別の間違い(勘違い)もある。下記だ。
摂取券番号をランダム20桁ほどのスパースな番号で発行して管理すれば(発行済みの番号かチェックするだけ)防げる。
「接種」でなく「摂取」と書いたのは、タイポだろうから、ご愛敬だろうが、肝心の話の内容がまったく間違っている。
「スパースな番号」というのは、「スカスカな番号」という意味で、あちこちに分載して配置されている番号のことだ。
仮に 「10桁 + 13桁」ならば、冒頭の 10桁は固定されているので、推定されやすい。それに対して、23桁の数字のあちこちに分散的に配置されていれば、元の数字は推定されにくい。
「だから、冒頭の 10桁を固定するよりも、23桁のスパースな番号の方が、安全である」
というのが、高木浩光氏の主張だ。だが、これは勘違いだ。
ネット上の攻撃者が攻撃するときには、23桁の数字を総攻撃する。つまり、10 の 23乗 の番号を総攻撃する。この場合、接種券番号が「冒頭の 10桁」であろうと、「スパースな番号」であろうと、関係ない。どっちみち、10 の 23乗 通りの試行錯誤をするのだ。その意味で、安全性はどちらも同じである。
では、何が違うか? 「元の番号を推定する」という作業だ。「冒頭の 10桁を固定する」という場合には、攻撃が成功したときに、接種券番号も自動的にわかってしまう。一方、「スパースな番号」ならば、攻撃が成功したときにも、接種券番号は必ずしも判明しない。
その意味で、「接種券番号を知られたくない」ということが最終目的であるならば、「スパースな番号」の方が安全性は高い。(だから、たとえばギフト券番号などでは、「スパースな番号」の方が適している。)
しかし今回は、そうではないのだ。“ 「接種券番号を知られたくない」ということが最終目的であるならば”という仮定は成立していないのだ。接種券番号が知られたからといって、別にどうってことはない。金を盗まれるわけではないし、単にネット上で悪戯をされるだけのことだ。そのくらいならば、たいした被害ではない。逆に言えば、攻撃者にとって、そのくらいのことではたいした利得にならない。(面白半分の悪戯心が満たされるだけだ。)
「接種券番号を知られたくない」ということは最終目的ではない。単に「ネット上の総攻撃を回避する」ということだけが最終目的だ。そのためには、十分に強度のある桁数を確保すればいいだけのことだ。その桁数は、通常は 14桁で十分だ。偏執的に桁数を増やしたい場合でも、23桁で十分だ。……そして、そういう桁数で、最終目的は達成されるのである。つまり、「攻撃に耐えられる」という最終目的は達成される。
ひるがえって、「接種券番号を知られたくない」ということを目的として、「スパースな番号にする」というのは、何のメリットもない。(接種券番号を知られてもいいからだ。)……それは、メリットがないが、他方で、「接種会場では、照合のための手間が 10桁から 23桁に激増する」という膨大なデメリットが生じる。……これでは、「百害あって一利なし」と言える。
それがつまり、「スパースな番号にする」ということの意味だ。
※ このことを知るには、「順列組み合わせ」の概念をよく理解しておく必要がある。ここでは 23C10 という式が用いられるが、その意味を、高木浩光氏はよく理解できていないようだ。
※ 接種券番号というのは、ただの事務処理用の番号なので、もともと「秘匿するべき情報」ではない。そのことは、銀行の口座番号と同様である。銀行の口座番号は、公開しても構わない。たとえば、振込用の口座番号は公開される。この番号は公開してもいいのだ。一方で、キャッシュカーの暗証番号は秘匿するべきだし、キャッシュカードそのものも他人には貸さない。こちらの防護がしっかりしていればいいのであって、口座番号自体はあえて秘匿しなくていいのだ。(なのに、「接種券番号を知られないようにする」という高木浩光氏の方針は、初めから方針を間違えている。守るべきものを取り違えている。それはいわば、銀行の金庫を厳重にするかわりに、銀行の出入り口を厳重にするようなものだ。そんなことをしても、効果がない一方で、やたらと不便になるだけだが。)
[ 補足 ]
本文の最後では、次のように述べた。
「23桁の数字を使うのは、桁が多すぎて不便なので、不可。」
同様に、(2) では、次のように述べた。
23桁の数字を提案しているが、これでは数字が多くなりすぎる。利用者の負担が大きくなりすぎる。人間は、10桁ぐらいならば容易に照合できるが、23桁も照合するのは、とても負担が大きい。
接種会場の場などでも、番号の照合に時間がかかって、作業能率が大幅に低下してしまうだろう。下手をすると、接種可能人数が低下するせいで、ワクチンの未接種者が大幅に増えてしまう。……これでは本末転倒だ。
このことは、本質的には、次のことを意味する。
「システムの外部からアクセスするときには、パスワードが必要だ。しかし、システムの内部からアクセスするときには、パスワードは必要ない」
具体的には、こうだ。
・ 本人または他人がネットでログインしたいときには、パスワードが必要だ。
・ 会場の受付係が予約の有無を確認するときには、パスワードは不要だ。
このうち、後者のことが大事だ。受付係は、本人の接種券番号を見て、予約の有無を確認する。「*********** という番号は、本当に予約を取っているかな?」と。そのとき、接種券番号を見るが、見るのは接種券番号だけでよく、パスワードまで見る必要はない。だから、10桁の番号だけで足りる。
一方、高木氏の方式では、接種券番号とパスワードが一緒になった 23桁の数字だけがある。本来ならば 10桁の番号だけで足りるのに、必ずパスワード込みで 23桁の番号を入力しなくてはならない。……これは、莫大な無駄手間だ。エラーも起こりがちだ。
結局、高木氏の方式では、「パスワードが不要な場合でも必ずパスワードを入力しなくてはならない」という莫大な無駄な手間が発生するので、非効率なのである。
数学的に言えば、エレガントとは逆で、野暮ったいのである。

ハッシュ値を 13桁にする、という方法の紹介。
「スパースな番号」が無意味だ、という話。
銀行の口座番号は公開しても構わないが、それと同様だ、という趣旨。
> 会場の受付係が予約の有無を確認するときには、パスワードは不要だ
という話。