novtanの日常

ネタです。ネタなんです。マジレスする人は撲滅すべき敵です。だからネタだってば!

「流出したパスワードはハッシュ化されているから安全」でないのはハッシュアルゴリズムの脆弱性の問題ではない

やけにMD5がーの人が多いけどさ
はてなブックマーク - 「ハッシュ化したから安全」と主張するのをそろそろやめようか | 日経 xTECH(クロステック)

そもそも、「ハッシュ化」ってのは正確には暗号化ではなく不可逆な符号化でしかないというところからちゃんと認識すべきだよね。手法が暗号化的なので暗号化と呼ばれるし、おおよそそれでも問題はないけどシステム屋としてはね。
MD5のMDがMessage Digestのことだってのが示すとおり、ハッシュはメッセージから生成される、そのメッセージを固有に表す符号のことであり、特徴として、違うメッセージであればおよそ違うDigest文字列ができる=内容のユニーク性を保ったまま短く要約できる、というもの。ここで大事なのはユニーク性が保たれる=元の内容をちょっとでも変えるとDigestの内容を同一にすることは大変困難、ということですね。

ハッシュアルゴリズムの脆弱性というのはこの同一の文字列が容易に得られないというところに対するもので、違う内容から同じものを生成できてしまう。これが衝突安全性の問題とされるもの。アルゴリズムの欠陥、あるいは量的な制約(出力される文字列の長さが短い=同一になるパターンの数が多い)によって文書の捏造を行ったことがハッシュで検証できなくなる=ニセの電子署名が通用する、というわけ。もっとも、例えばソースの作成者の正当性検証のために電子署名を使っていたとして、ソースコードの中に意図的なバグを仕込んだ上で、ニセの署名が同一のハッシュになるようにする、というのはようなその改竄とは無関係なところにいろんなコードを仕込むことになるから不自然な差分が出てバレる、みたいな話なので、直ちにやべーというわけではない、というもの。

で、今回のネタはそういう話とはまた違って、パスワードのハッシュ化とは一体何ってこと。
これ、別にパスワードの改竄チェックをするわけでもないので、実質的にはハッシュの暗号化的性質を使って暗号化の代わりに使っているということになりますね。言ってしまえば「単に平文保存しない」だけの話。で、このハッシュ化の際に、元の文字列をただハッシュアルゴリズムを通しただけで保存する、という点の問題なわけです。というのも、同一文字列からは必ず同じハッシュ化された文字列が生成される、ということは、特定のパスワード文字列に特定のアルゴリズムを使った場合の出力は必ず一定。であるならば、主要なハッシュアルゴリズムで主要なパスワードで使われる文字列をハッシュ化した結果の辞書、なんてのは当たり前のように生成可能なわけです。

つまり、単にハッシュ化しただけのパスワードが流出したということはパスワード文字列が漏れたのとほぼイコール、時間稼ぎにもなりませんよ、ということね。

だから、ストレッチングとかSaltとか、システム側で付与する(つまり、入力者がコントロールできない)文字を加えたハッシュ化が強度を高める目的として使われるわけですね。先に説明したハッシュの原理から言って、Saltやストレッチ回数は算出不能なわけです。

ところが、目の前には最終的な答えがある。ということはですよ、目の前の答えに対するブルートフォース攻撃をすることが可能ってことになりますね。つまり、Saltが固定だったりすると一般的に使われる可能性のあるSalt文字列をパスワード辞書とくっつけて適当な回数ストレッチングしてハッシュ化した結果を得る、という処理を条件を変えてやり続ければいつかは答えにたどり着く。だから、答えが流出しているという時点で非常に危ない。なんだったらすでに知られているハッシュ化の方法で得た文字列と一致する文字列が一つでも見つかればSaltとストレッチ回数含め流出したのと一緒です。Salt設定のヒントになる他のユーザー情報項目も流出しているわけで。

これはどんなハッシュ化アルゴリズムを使っていても全く同様の問題なので、まだMD5使ってんのみたいな話は全くここでは関係ないし、この手の使い方でMD5だと他に比べて著しく脆弱、ということもないはずなんだよな。