パスワードの保存に関する多くの推奨事項は、hash(salt + password)
ではなくhash(password + salt)
を推奨しています。
最初にソルトを配置しないと、攻撃者がソルトのバイトでハッシュ関数の状態を事前に計算できるため、攻撃者がパスワードをブルートフォースするのがはるかに速くなります。パスワードのバイトを使用してハッシュの計算を終了します。
つまり、ブルートフォースの反復ごとに、intermediateHashState(password)
全体ではなく、パスワードのハッシュhash(salt + password)
のみを計算する必要があります。
また、パスワードの後にソルトが置かれている場合、攻撃者はこのショートカットを使用できません。
この利点はありますか?それは重要ですか?
パスワードの使用に推奨されるハッシュ関数には、この利点はありません。実際、重要なハッシュ関数が実際にあるかどうかはわかりませんが、そこに包括的なステートメントを作成したくありません。
代わりに、ハッシュ関数は各ステージで入力全体の一部を混合します。たとえば、入力がABCDEFGHIJKLMNOPQRSTUVWXYZ
の場合、最初のステップは、最初の文字を最後の文字とペアにし、入力がなくなるまで繰り返すようなものです。これはAZBYCXDWEVFUGTHSIRJQKPLOMN
を与えます。 「塩」がABCDEF
で、パスワードが残りの場合は、パスワードをPASSWORD
に変更します。この例の最初のステップの出力はADBRCODWESFSPA
で、少しでも元のハッシュであなたを助けません。
これはほんの一例です-実際のハッシュ関数はバイナリ値に対して機能し、いくつかの違いのために、より複雑な混合を実行します-しかし、ソルトが非常に早い段階で出力を変更する場所は問題ではないことがわかります。
ハッシュ関数への入力で変更される単一のビットが出力ビットの約50%を変更する必要があることを示唆する原理( アバランシェ効果 )もあり、ほとんどのハッシュ関数は、 MD5などの安全でないと見なされている場合は、これに従ってください(上記の私の例ではそうではありません!)。
基本的に、システムに他の欠陥がない限り、提案した方法でハッシュの一部を事前計算することはできません。何らかの理由でソルトをハッシュし、出力の前半を取得して、パスワードのハッシュの後半にボルトで保存すると、理論的な弱点が生じるため、計算するだけで済みます。パスワードのハッシュ。
実際、あなたは反対の方法でそれに取り組んでいます。
hash(salt + password)
を実行すると、saltを事前に計算でき(ただし、以下の注を参照)、それらすべての試行のパスワード候補のみをハッシュできることは事実です。塩をまったく使用しなかった場合の費用は同じです。
ただし、ソルトの目的は、1つのハッシュの総当たりを難しくすることではなく、同じユーザーが同じパスワードを選択した場合でも、異なるユーザーのハッシュが異なるようにすることであり、クラッキングの労力を複数のユーザーに適用することはできません。
MD5ハッシュを使用していた場所にPaypalデータベースハッシュをダンプしたとしましょう。パスワード「Paypal」、「Paypal」、「Paypal123」を確認したい...
彼らがMD5(パスワード)を使用している場合は、それらのいずれかを簡単にハッシュして、そのような弱いパスワードを使用している人がいるかどうかを確認できます。
彼らがMD5(塩+パスワード)を使用している場合は、すべての人に対して部分的なMD5(塩)を事前計算できますが、各ユーザーの各パスワード候補をハッシュする必要があります。
彼らがMD5(password + salt)を使用した場合、候補となるパスワードごとに部分的なMD5(password)を事前に計算してから、各ユーザーにソルトを適用できます。
#1は明らかにここで最悪です。パスワードとソルトのさまざまな長さ、およびユーザー数に基づいて、#2と#3の間で議論することができますが、私は#2が望ましいと考えます。長さのみに基づくと、パスワードの強制最小長はおそらくソルトサイズよりも長くなります。しかし、#3構成には他の弱点もあるのではないかと思います。
あんまり。
まず、多くのハッシュ関数はブロックで機能し、ブロックサイズよりも小さい値の事前計算では、「事前計算されたバイト」のコピーが単に格納されます。 99%の場合、saltとpasswordの両方の長さがブロックサイズよりも短くなるため、実際には事前計算は行われません。そのためには、本当に長い文字列を使用する必要があります。
さらに、最新のパスワードハッシュ関数は、ブルートフォーシングを高価にするためのより高度な手段を使用しない場合でも、最低でも多くの反復を使用し、最適化は最初の反復にのみ適用されます。
いずれの場合も、単にソルトとパスワードを連結するのではなく、それらを組み合わせる最も安全な方法は、それらに対して [〜#〜] hmac [〜#〜] を実行することです。より良い方法。
パスワードの保存に関する多くの推奨事項は、
hash(salt + password)
ではなくhash(password + salt)
を推奨しています。
これらの推奨事項は明らかに悪いものです。なぜなら、彼らがあなたに伝えるべきことは、次のような目的のために特別に設計されたパスワードハッシュ関数を使用することだからです(新しいものからより良いものへ、古いものから悪いものへの大まかな順序で):
これらの機能は次のいずれかです。
password_hash()
in PHP );password_verify()
in PHP )。パスワードとソルトを手動で連結している場合、それは間違っています。
とは言っても、一般的に、パスワードハッシュ関数が最初にソルトを吸収し、その後にパスワードを吸収する方が良いでしょう。どうして?一般に、その順序は事前計算攻撃への耐性が高いためです。攻撃者はパスワード優先の順序で、一般的なパスワードに対応する中間状態を事前計算できます。おそらく、これを利用してソルトハッシュを他の方法よりも速く計算するある種の大きなテーブルを作成する巧妙な方法があるでしょう。 salt-first順序はこれを不可能にしますが、塩がランダムな場合はさらに不可能になります。
最初にソルトを配置しないと、攻撃者がソルトのバイトでハッシュ関数の状態を事前に計算できるため、攻撃者がパスワードをブルートフォースするのがはるかに速くなります。パスワードのバイトを使用してハッシュの計算を終了します。
いいえ、要点は攻撃者がパスワードデータベースを盗む前にソルトを学習することは想定されていないためです。あなたが言及しているこの事前計算のビットは、適切に設計されたパスワードハッシュ関数のコストに比べてわずかな高速化をもたらすだけであり、事前計算された状態は1つの個別のパスワードエントリを攻撃するのにのみ適しています(とにかく要件である重複ソルトがないと仮定します)。
対照的に、パスワード優先の順序では、次のことができます。
上記の回答はいくつかの有効なポイントを提起しますが、それらは完全に正しいとは思われないため、特定のハッシュ関数には実際に "$ pass。$ salt"のクラッキング速度に大きな違いをもたらす弱点があることに注意してくださいまたは「$ salt。$ pass」。
たとえば、md5を参照してください。 atom( https://hashcat.net/forum/thread-8365.html )によると、hashcatパスワードクラッキングソフトウェアの作成者:
HashcatがMD5の弱点を利用して追加のアクセラレーションを取得する方法では、入力データの最初の4バイトのみを変更する必要があります。この部分は固定されているため(塩のため)、加速を使用できません。
それはクラッキング速度にかなり反映されます。
Titan RTXでは、md5($ pass。$ salt)の速度は63819.9 MH/sで、「のみ」の34696.2 MH/sのmd5($ salt。$ pass)の速度のほぼ2倍です。
他のハッシュアルゴリズムにも同様の違いがあります。パスワードクラッキングソフトウェアの開発者とコミュニティは、速度を改善するための弱点とショートカットを見つけるためにかなりの時間を費やしています。したがって、クラッキングの観点からは、次のような現在のhashcatベンチマークを確認することをお勧めします https://Gist.github.com/Chick3nman/5d261c5798cf4f3867fe7035ef6dd49f さまざまなソルトパスワードの速度を比較する-バリアント。
そのリンクが失われた場合、次のコマンドを使用して独自のベンチマークを生成することもできます。
hashcat -b