ハッシュが DESベースの暗号化 関数でPHP=で行われ、ハッシュとソルトの両方が攻撃者に知られている場合、ハッシュされたパスワードを回復できますか?
次の例を検討してください。
$salt = 'mysalt';
$pass = 'mypass';
$hashed_pass = crypt($pass, $salt);
// $hashed_pass = myDUAMR/WMo7.
John the Ripperはこれを破ることができることを知っていますが、パスワードを返すのではなく、同じハッシュ値を作成するために使用できる文字列を返します。特定のシナリオで実際のパスワードを回復できますか?
John the Ripperは、考えられるパスワードを非常に迅速に試すことで機能します。それは常にDESベースの暗号を壊すことはなく、少なくとも簡単にはできません。
DESベースのハッシュ関数では、パスワードは最大8文字で、各文字に7ビットのみが使用されます(上位ビットは無視されます)。ユーザーがキーボードのある時点でパスワードを入力したことを考えると、各文字(スペース[32]からチルド[127]までのASCII文字)には95個の可能な値があるため、6704780954517121の潜在的なパスワード(つまり1 + 95 + 952 + 953 + ... + 958)。それはかなりたくさんあります。 PCですべての可能性を列挙するには、少なくとも数週間かかります。しかし、それはまだ技術的に実現可能です。
DESは暗号化機能ですが、DESベースの暗号化はDESではありませんDES。内部関数が(saltによって)変更され、25回実行されます。さらに重要なことに、キーとメッセージの役割が交換されます。最終的な結果として、「crypt」という名前は不適切です(従来のものですが)。これはencryption関数ではなくなりました。それは「DESベースのハッシュ」と呼ばれるべきです。これが意味することは、同じ値にハッシュする2つの異なるパスワードが存在する可能性がある(実際に存在する可能性がある)ことです(同じソルトを使用していても)。たとえば このブログ投稿 は、ソルト「hi
」を使用すると、「cqjmide
」と「ifpqgio
」の両方が同じ値にハッシュされることを示します"_hiH9IOyyrrl4k
_"(ブログの投稿では、これが最初に公に知られているそのような衝突であると主張しています。これは難しくないので問題がどれほど興味深いかを示しています。これらは64ビットの値なので、衝突を見つけるためのコストです。約2です32crypt()
の呼び出し;最初に公開された衝突が2010年後半にのみ出現したことは、それ以前に実際に誰も試していないことを証明しているにすぎません。
(注:ブログの投稿とは異なり、衝突を検出する可能性はパスワードハッシュシステムのセキュリティにまったく影響を与えません。そのような衝突が発生しやすいため、DESベースのハッシュは使用しないでください。ただし、入力スペースと出力スペースが小さすぎて、速すぎるためです。)
したがって、saltとhashだけでは、「the」パスワードを特定する方法はありません。情報がそこにないだけだからです。考えられるすべてのパスワードを列挙することで、一致するパスワードのリストを作成できますが、ユーザーがどのパスワードを考えたのかを見分ける方法はありません。ただし、ここで重要な点です。パスワード検証システムでDESベースのハッシュの結果を使用するマシンはどちらも認識できません。saltとハッシュ値に一致するパスワードはすべて他と同じように、適切なパスワード。ソルトとハッシュが「_hiH9IOyyrrl4k
_」の場合、「cqjmide
」と「ifpqgio
」の両方が受け入れられます。パスワードが「cqjmide」であると思っていても、私はまだできます「ifpqgio」をパスワードとして使用して、自分の名前でログインします。
ただし、可能なハッシュ値の大部分には一致するパスワードが1つしかないため、徹底的な検索ではそのパスワードのみが見つかり、他のパスワードは見つかりません。
同様に、最初の8文字のみが使用されるため、40文字の長さのパスワードを使用することができ、そのうちの32文字はDESベースのハッシュによって完全に無視されます。それらは単に削除され、計算されたハッシュにまったく影響を与えないため、ハッシュ値からそれらを回復する方法はありません。
ハッシュアルゴリズムを使用して、特定のパスワードのすべての衝突を計算することはできません。衝突は無限です。 Johnがハッシュダイジェストと一致するパスワードを提供できる場合、理論的には実際のパスワードを回復できます。ただし、次のことはできません。
パスワードを見つけるためにできる最善の方法は、辞書攻撃を試し、ユーザーがこの辞書の1つの単語(または計算したいバリエーション)を使用したと想定することです。 2つの異なる辞書Wordから2つの衝突を見つける可能性は低くなります。したがって、これにより、元のパスワードが確実に保持されます。しかし、もちろんこれは単なる統計です。