ハッシュ

1997 年頃だったか、マイクロソフトが 「ActiveX」 というインターネットの新しい技術を発表した。今我々が使っているインターネットエクスプローラーという名前のブラウザも、この頃初期のバージョンが発表された。

我々技術者は、その新しい技術を使ってソフトを開発しなければならなくなった。マイクロソフトのずさんなセキュリティのために、全世界のウィンドウズを使うユーザーは現在、ウィルス付きメールや月に 1度のパッチを充てなければならないという煩わしさに悩まされ続けているが、すべてはここから始まった。

この頃、マイクロソフトはそれぞれのソフトウェアに世界で一意(=ユニークな)番号を与えるから、それを使え、と言い出した。

世界中のプログラマは、個人や企業に関わらず、ウィンドウズのプログラムを作ったら、そのプログラムを識別するために番号を付けるのだ。

ちょっとパソコンに詳しい人なら、ウィンドウズの 「レジストリ」 というコトバを聞いたことがあるだろう?実は、そこにソフトの番号がたくさん貯められているのだ。

しかしすぐにこんな質問が思いつく。

「いったい誰がどうやって他のプログラムとバッティングしないように番号を振るのか?」

まず自分で勝手に振ったら、世界で無数にあるウィンドウズのソフトの番号とバッティングしそうだ。それは容易に想像できる。

では、マイクロソフトにいちいち申請をして番号を振ってもらうのか?オンラインですべて自動で行われたとしても、ちょっと面倒だ。マイクロソフト自身もそんな番号を管理するのはコストがかかって仕方ないだろう。

実はマイクロソフトは、自社のソフトウェア開発のためのソフト(ソフトを作るソフト)が、自動的に番号を振るから、それを使え、といっていた。

そんなことが可能なのだろうか?世界で、本当に自分しか所有しない番号、、しかも誰ともその番号を調整しないで・・・

このとき、ウィンドウズのソフト開発に非常に詳しい同僚に質問してみたが、実は上の説明をされただけで、どうしてそうなるのかまでは説明してもらえなかった。しかし、今ならその仕組みを説明できる。ヒントは、件名にある「ハッシュ」だ。まずはググってみよう。

上では、マイクロソフトが「世界で唯一の番号を各人が作ったソフトに自動的に割り振る」という話をした。

実際にそんなことは可能なのだろうか?答えは、「事実上」 可能なのである。事実上と、枕詞がつく理由は、「十分に実用的に耐えうる」からである。

それには、このメールのタイトルのハッシュというものを使う。

中高で 「関数」 を習ったが、ハッシュとは関数の一種だ。

この関数は特殊で、A というものを入れると B というものが出てくるが、一度 A を B に変換してしまうと、元のAには絶対に戻せない、というものだ。戻せないというより、元のAは何だったかわからない、といった方が正しい。

たとえば 1234 を入力すると 7890 が出てくるような感じである。7890 から 1234 を復元する方法はこの世に存在しない。1234 を入力すると必ず決まった値である 7890 が出てくるもので、1234 を入力したときの 7890 という値は、この世の中で(おそらく)あなたの他に誰も 7890 という値を持っていないものである。

では 1234 から 7890 どうやって計算するのか?というと、複雑な計算手順が必要らしく、実は私にもわからない。ひとつ言えるのは世界で唯一の数字はどんなものか?と少し考えると、「時刻」 があると思う。その計算をした瞬間の時刻をそのまま数値化すれば、あなたとまったく同じ計算をした人はおそらくいないだろうから、時刻は唯一であると言える、というものだ。

しかしやはり本当にその瞬間に全世界で同じ計算をした人が存在しないかと言われたら、ひょっとしたらいるかも知れない。だから、時刻という値はハッシュであることの最有力候補であるけれども、もっともっとバラバラな数字が必要だ。だからハッシュを計算する関数、つまりハッシュ関数はもっと複雑な計算を行い、その出力が世界で唯一であることを数学的に保証する、というものなのだ。

ハッシュは、乱数(ランダムな、バラバラな数字)に見えて、実はインプットが同じなら出力も常に同じ、という性質を持っている。

ではハッシュは日常生活でどんなところに使われているのだろう?

  • プログラムを世界中でたった1つに特定する。→マイクロソフトのソフトウェア ─── Excel や Word、IE でさえも ─── 世界中で一意の番号が振られている。
  • メールのメッセージ ID。メールには、 d2384969b8419d7a8273c53a0c51d819@twinkle.cc などという番号が振られている。もし同一時刻に同一者から同一内容が送られれば この ID は同じである。1 秒でも遅れて同一内容のメールを送ってもこの値はまったく違ったものになる。
  • 本人確認の手段。社員番号が 12435700 で、誕生日が 19700101、名前が「アオイヤスヒコ」というデータからハッシュ値を求める。この 3 つの要素を持っているのが世界中でただ 1 人だったとすると (実際には 1 人に特定するためにもっとたくさんの要素を 組み合わせる必要があるのだが)、ここから生成されたハッシュ値、たとえば 2a2c110bfc7f4875f0ab7a5393b7a7bf という文字列は、アオイヤスヒコが持っている 個人情報からしか生成されない。そのため、この値は本人確認に使用できる。この文字列を伝えられた側は、この文字列からアオイヤスヒコであることは確認できるが、元の個人情報を復元できないのだ。
  • 医療分野では、上を応用すると、本人の身元を明かさないまま、統計データを処理できる。統計データを処理するにあたって、多くの場合はその本人の「本名」はいらないからである。本名自体から求めたハッシュ値を使えば良いのである。
  • パスワードの保存。実は、このことが書きたくてハッシュのことをつらつら書いてきた。 ウェブサイトではユーザー名とパスワードを入力させられるケースが多々ある。このとき、ユーザー名は誰に知られてもいいが、パスワードは本人のみ知っているものである。素人がシステムを作ると、パスワードを生のままサイト側に保存してしまう。もう少し気の利いたエンジニアだと、パスワードを暗号化して入れる。しかしパスワードを暗号化すると、パスワードが漏れてしまったとき、復元方法もバレると結局もとのパスワードもバレてしまう。そこでハッシュの登場である。システムには、ユーザーが入力したパスワードのハッシュ値を記録・保存しておく。ユーザーがサイトにアクセスしてパスワードを入力したときには、常にハッシュ値を計算してシステム内に保存されているものと 等しいか比較するのである。こうすれば、パスワードとして保存していた 「つもり」 のハッシュ値が万が一漏れたとしても、誰もその文字列からは元のパスワードを復元 することはできない。この方式は拙作のサイト i-Services でも使っている。

    実はもっといろいろな応用があるが、ちょっと難しかったと思うので今回はここまで。

    Trackback URL for this post: https://econo.twinkle.cc/trackback/97