web-dev-qa-db-ja.com

キー導出関数と(ソルト)ハッシュの違いは何ですか?

この投稿 を見ると、主な違いはKDF出力に「特定のランダム性プロパティ」があることであり、それが何を意味するのか理解できません。その「特定のランダム性」はレインボーテーブルと事前計算済みのものから保護するためのものであると仮定します。

しかし、適切なソルティングでハッシュを使用すると、これらの攻撃から保護することもできます。その意味で、この2つのツールに違いはなく、実装のみが異なると私は信じています。

また、速度の面でユーザーエクスペリエンスを損なうことなく、架空の攻撃を減速させるために、KDFの他の目的がslowで十分であることも知っています。まあ、厳密な意味では、これは、あまりクリーンではない場合でも、ハッシングでいくつかの無意味な操作(for(i = 0; i < 1000000; i++);など)を追加することでも実現できます。

それで、違いは何ですか?他のどれよりも優れていますか?いつ1つを使用しなければならないでしょうか。

3
Julen

KDFには実際には2種類あります。 1つの種類は、(別のキーのように)高エントロピー入力からキーを派生するように設計されています。これは、HMACのような高速キー付きハッシュで実行できます。他の種類は入力としてパスワードを取ります。パスワードは低エントロピーです。彼らは本質的に総当たりすることは非常に難しいことではありません。したがって、適切なパスワードハッシュは遅くなる必要があります。

あなたの質問では、for (i=0; i<bignum; i++);を追加するとハッシュが遅くなると述べました。これは実際には完全に無意味です。攻撃者はあなたのルールに従う必要はありません。攻撃者がハッシュのコピーを持っている場合、ハッシュはパスワードを保護する必要があります。攻撃者がハッシュをすばやく計算できる場合は、どれだけゆっくりとハッシュを計算しても問題ありませんあなたハッシュを計算します。ハッシュは本質的に遅い必要があります。正当なサーバーよりも速く評価するためのショートカットはありません。

「ランダム性」は、KDFがキーを生成する必要があるためです。彼らはレインボーテーブルを含む事前計算とは何の関係もありません。暗号化アルゴリズムは通常、キーについて特定の仮定を行います。特に、彼らは通常、可能なキーのセットから完全にランダムに選択されたと想定します。キーも一定の長さであることが期待されています。それらの導出関数には、任意の長さの出力が必要です。対照的に、パスワードハッシュが出力に対して多くの構造を持つ場合は問題ありません。おそらく、隣接するビットが同じ値を持つ確率は70%です。多分それは128ビットのエントロピーを4096ビットの出力に広げます。元に戻すのが難しい限り、それは細かいハッシュですが、キーとしては不適切です。

安全なパスワードベースの鍵導出関数は、安全なパスワードハッシュです(PBKDF2は、実際には大きな3つのハッシュの1つです)。その逆は必ずしも真ではありません。どちらを使用するかは簡単です。パスワードベースのキー導出関数を使用してパスワードからキーを導出し、ハッシュを使用してパスワードを格納します。

8
cpast