ここで最もupvoted答えは強調して何に反して、非単射(すなわち、同じ値にハッシュする複数の文字列があること)違いによる暗号ハッシュ関数の大規模な(潜在的に無限の)入力サイズと固定出力サイズの間ではありません重要なポイント –実際には、これらの衝突ができる限り発生しないハッシュ関数を好みます。
この関数を考えてみてください(質問として、PHP表記で)。
function simple_hash($input) {
return bin2hex(substr(str_pad($input, 16), 0, 16));
}
これにより、文字列が短すぎる場合はスペースが追加され、文字列の最初の16バイトが取得され、16進数としてエンコードされます。MD5ハッシュと同じ出力サイズ(32桁の16進文字、またはbin2hex部分を省略した場合は16バイト)です。
print simple_hash("stackoverflow.com");
これは出力します:
737461636b6f766572666c6f772e636f6d
この関数には、MD5に関するCodyの回答で強調表示されているものと同じ非注入性プロパティもあります。コンピュータに収まる限り、任意のサイズの文字列を渡すことができ、32桁の16進数のみを出力します。もちろんそれは単射的であってはなりません。
しかし、この場合、同じハッシュにマップする文字列を見つけることは簡単です(ハッシュに適用するだけでhex2bin
、それが得られます)。元の文字列の長さが16(この例のように)だった場合、この元の文字列も取得されます。入力の長さが非常に短いことがわかっていても、MD5ではこのようなことはあり得ません(一致する入力が見つかるまですべての可能な入力を試行すること以外は、ブルートフォース攻撃など)。
暗号化ハッシュ関数の重要な前提は次のとおりです。
- 特定のハッシュを生成する文字列を見つけるのは困難です(プリイメージ耐性)
- 指定された文字列と同じハッシュを生成する別の文字列を見つけるのは難しい(2番目のプリイメージ耐性)
- 同じハッシュ(衝突抵抗)を持つ文字列のペアを見つけるのは難しい
明らかに、私のsimple_hash
機能はこれらの条件のどちらも満たしていません。(実際、入力スペースを「16バイト文字列」に制限すると、私の関数は単射になり、したがって、2番目のプレイメージ耐性と衝突耐性さえ証明できます。)
現在、MD5に対する衝突攻撃が存在します(たとえば、特定の同じ接頭辞を使用しても、同じハッシュを持ち、かなりの作業ではあるが不可能ではない作業で、文字列のペアを生成することが可能です)。したがって、使用しないでください。重要なものにはMD5。まだプリイメージ攻撃はありませんが、攻撃は改善されます。
実際の質問に答えるには:
結果の文字列をたどることが不可能になるこれらの関数については何ですか?
MD5(およびその他のハッシュ関数は、Merkle-Damgardの構築に基づいて構築)が効果的に行うことは、結果の暗号文をハッシュとして使用して、メッセージをキーおよび一部の固定値を「プレーンテキスト」として暗号化アルゴリズムを適用することです。(その前に、入力はパディングされてブロックに分割されます。この各ブロックは前のブロックの出力を暗号化するために使用され、逆の計算を防ぐためにその入力とXORされます。)
現代の暗号化アルゴリズム(ハッシュ関数で使用されるものを含む)は、平文と暗号文の両方が与えられた場合(または攻撃者がそれらのいずれかを選択した場合でも)に、キーの回復を困難にする方法で作成されています。それらは一般に、各出力ビットが各キービット(数回)と各入力ビットによって決定されるように、多くのビットシャッフル操作を行うことによってこれを行います。この方法では、完全なキーと入力または出力のいずれかがわかっている場合にのみ、内部で何が起こっているかを簡単にたどることができます。
MD5のようなハッシュ関数とプリイメージ攻撃(単一ブロックのハッシュされた文字列を使用して物事を簡単にするため)の場合、暗号化関数の入力と出力だけがあり、キーはありません(これが探しているものです)。