チェックサムのことを知っていればハッシュも分かる

ハッシュ(一方向ハッシュ)って何、と聞かれたら、まずは「チェックサムのすごいやつですよ」 と答えることにしています。もちろん、それでピンと来ないようならもうすこし改まった説明を始めますが、「ああ、チェックサムね」と拾ってくれるようなら話がすこし早くなるな、という気持ちからです。

チェックサムとかチェックデジットと呼ばれるものは、一定の長さの数字とか記号の集まり(文字列)が誤って入力されないよう、記号全体のうち1桁とか2桁を、他の記号の「足し算」の結果にしておくという仕掛けです。ただし、単純な足し算ではなくて、どの桁は7をかけてから足す、とか、どの桁は13をかけてから足す、とか、ちょっと工夫されたルールになっていることが多いです。また、数字でなくて文字の場合は適当なルールで数に換算する、とか、チェックサムの桁があふれたときにどうするか、とか、まあ色々あるでしょう。ともかく、クレジットカード番号など、入力されたなんらかの文字列があったときに、それがそもそも存在しうる番号なのかどうかを簡易に判定して、あらかじめ誤入力とかイタズラ入力を防ぐことができるというわけです。(16進ダンプをモニタで入力するときの誤入力も防ぐことができる… なんて思い出もありますが、これは特に説明を加えません。分かる人にだけ通じればよいです)

ハッシュというのは、もっと、入力ミスがあったときに厳密にそれを見つけたい、というときに使われる技法です。チェックサムならせいぜい2桁の数とかですが、ハッシュは、すこし古めのMD5という計算法でさえ、10進数で39桁くらいの巨大な「チェックサム」をつくり出します。2桁のチェックサムなら、たまたま誤った入力が「正解」のチェックサムを偶然出して、有効判定をもらってしまうことが可能ですが、39桁の巨大な数なら、まず「かぶった」チェックサムになる誤入力はありえないだろう、と容易に予想できますね。

ハッシュを計算する対象は、クレジットカード番号みたいな10数桁のデータだけでなく、大きなファイル全体、という場合もよくあります。数ギガバイトみたいな巨大なファイルでも、本質的には一つながりの長い数字と変わらないのですから、全体のチェックサム(ここではハッシュ)を計算できるのです。大きなファイルのハッシュは、ダウンロードが正常にできたかどうかの判定なんかに便利です。

ハッシュの計算式はとても複雑なもので、ほんのちょっとだけ異なるようなデータについても、ガラッと違った「チェックサム」が出てくる、という特徴があります。データの中のある部分を1だけ足し、ある部分を1だけ引いたら、もしかして同じハッシュが出てくるのでは? と、なんとなく想像したりもするでしょうけれど、そんなことはありません。むしろ、同じハッシュを計算できるようなデータをつくり出すのが非常に困難、というのがこの技術の強力な特徴であるとされているくらいです。すこし言葉を換えると、「同じハッシュを持つデータを捏造(ねつぞう)することは不可能」ということです。

あえて「不可能」と言い切りましたが、ここは、世界中の暗号学者が不断に議論を重ねているところで、本当に不可能なのかは分かりません。でも今のところは、「総あたり」みたいなメチャクチャ非効率な方法で探さない限りそういったイタズラはできなさそうだ、というのが一定の結論になっています。39桁のチェックサムが同じになるまで「総当たり」の計算なんてやれませんよね。1京の1京倍くらいの回数の計算をしても、なお39桁の全パターンを網羅できませんから、まあ「不可能」といっても差し支えないよね、ということです。

ここまで書いてからアレですが、ホントは、MD5は、「かぶり」を発見する方法がすでに解明されています。また、コンピュータ自体もメチャクチャ速くなったので、「1京の1京倍」みたいな回数の計算も、本気の本気になればまあやれる、というくらいになってしまいました。なので今主流で使われているハッシュの計算法はまた別のものなんですが、ともかく、チェックサムというちょっと古めの技法が、ハッシュという割と新しい技術のことを理解するとっかかりになることができる、という話でした。

MD5くらいのハッシュでも、偶然同じ値を計算しちゃうことが「ほとんどない」のだから、充分便利な技法なんじゃないの、とも思えますし、それで実際充分なときもあるのですが、「本気の本気でチャレンジしても、絶対に同じハッシュが計算できない」ということが要求される場面というのも世の中にはあるということなんですね。ここでは詳しく説明しませんが、たとえば「電子署名」なんていうものがそれです。署名というくらいですから、赤の他人がそれを捏造することが可能、なんてのは困りますもんね。