ハッシュのソルティングに関する質問が定期的に寄せられ、この件についてかなりの混乱があるように思われるため、この回答を拡張しました。
塩とは?
ソルトは、ハッシュ アルゴリズムの入力に追加される、固定長のランダムなバイト セットです。
ハッシュのソルティング (またはシード) が役立つのはなぜですか?
ハッシュにランダムなソルトを追加すると、同じパスワードが多くの異なるハッシュを生成することが保証されます。ソルトは通常、ハッシュ関数の結果とともにデータベースに保存されます。ハッシュのソルトは、いくつかの理由で適切です。
- ソルティングは、事前計算された攻撃 (レインボー テーブルを含む)の難易度/コストを大幅に増加させます。
- ソルティングにより、同じパスワードが同じハッシュにならないようにします。これにより、2 人のユーザーが同じパスワードを持っているかどうかを判断できなくなります。さらに重要なのは、同じ人が異なるシステム間で同じパスワードを使用しているかどうかを判断できないことです。
ソルティングはパスワードの複雑さを増すため、辞書攻撃と誕生日攻撃の両方の効果が大幅に低下します。(これは、ソルトがハッシュとは別に保存されている場合にのみ当てはまります)。
- 適切なソルティングにより、事前計算攻撃に必要なストレージが大幅に増加し、実用的でなくなるまで増加します。(128 ビット値にハッシュ化された 16 ビットのソルトを使用した、大文字と小文字が区別される 8 文字の英数字パスワードは、レインボー リダクションなしで 200エクサバイト弱を占めることになります)。
塩を秘密にする必要はありません。
ソルトは秘密鍵ではなく、各インスタンスに固有のハッシュ関数を作成することによってソルトが「機能」します。ソルト付きハッシュでは、ハッシュ関数は1 つではなく、考えられるすべてのソルト値に対して 1 つです。これにより、攻撃者は、 1 つのパスワードを攻撃する場合のN倍未満のコストで、ハッシュ化されたN 個のパスワードを攻撃できなくなります。これが塩のポイントです。
「秘密のソルト」はソルトではなく、「キー」と呼ばれ、ハッシュを計算するのではなく、メッセージ認証コード(MAC) を計算することを意味します。MAC の計算はトリッキーな作業であり (単にキーと値をハッシュ関数にまとめるよりもはるかにトリッキーです)、まったく別のテーマです。
ソルトは、それが使用されるすべてのインスタンスでランダムでなければなりません。これにより、攻撃者はすべてのソルト付きハッシュを個別に攻撃する必要があります。
ソルト (またはソルティング アルゴリズム) が秘密であることに依存している場合は、あいまいさによるセキュリティの領域に入ります(機能しません)。ほとんどの場合、salt シークレットからセキュリティを強化することはできません。ほのぼのとした安心感が得られます。したがって、システムをより安全にする代わりに、現実から気をそらすだけです.
では、なぜソルトはランダムでなければならないのでしょうか?
技術的には、ソルトは一意である必要があります。ソルトのポイントは、ハッシュされたパスワードごとに区別することです。これは全世界を意味します。オンデマンドで一意のソルトを配布する中央組織がないため、次善の策に頼る必要があります。これは、予測不可能なランダム ジェネレーターを使用したランダム選択であり、できれば衝突を起こりにくくするのに十分な大きさのソルト スペース内で行います (同じものを使用する 2 つのインスタンス)。塩分値)。
ユーザーIDなど、「おそらく一意」のデータからソルトを導出しようとするのは魅力的ですが、そのようなスキームは、いくつかの厄介な詳細のために失敗することがよくあります。
たとえば、ユーザー IDを使用すると、個別のシステムを攻撃する一部の悪者が、リソースをプールして、ユーザー ID 1 から 50 の事前計算テーブルを作成する可能性があります。ユーザー ID はシステム全体で一意ですが、世界規模ではありません。
同じことがユーザー名にも当てはまります。Unix システムごとに 1 つの「ルート」がありますが、世界には多くのルートがあります。「ルート」用のレインボー テーブルは、何百万ものシステムに適用できるため、努力する価値があります。さらに悪いことに、そこには多くの「bob」もあり、その多くはシステム管理者のトレーニングを受けていません。彼らのパスワードは非常に弱い可能性があります.
一意性も一時的なものです。ユーザーがパスワードを変更する場合があります。新しいパスワードごとに、新しいソルトを選択する必要があります。そうしないと、攻撃者が古いパスワードのハッシュと新しいパスワードのハッシュを取得して、両方を同時に攻撃しようとする可能性があります。
暗号的に安全で予測不可能な PRNG から取得したランダムなソルトを使用することは、ある種のやり過ぎかもしれませんが、少なくとも、これらすべての危険から確実に保護します。個々のソルトが何であるかを攻撃者が知るのを防ぐことではなく、かなりの数の潜在的なターゲットで使用される大きくて太ったターゲットを攻撃者に与えないことです. ランダムな選択により、ターゲットは実用的な範囲で薄くなります。
結論は:
ランダムで均等に分散された高エントロピー ソルトを使用します。新しいパスワードを作成したり、パスワードを変更したりするたびに、新しいソルトを使用してください。ハッシュされたパスワードとともにソルトを保存します。大きなソルトを優先します (少なくとも 10 バイト、できれば 16 バイト以上)。
ソルトは、悪いパスワードを良いパスワードに変えません。攻撃者は、少なくとも、不正なパスワードを解読するたびに、辞書攻撃の対価を支払うことになります。
有用なソース:
stackoverflow.com:パスワード ハッシュの非ランダム ソルト
Bruce Schneier: Practical Cryptography (本)
Matasano セキュリティ:レインボー テーブルで十分
usenix.org: 1976 年以来、Unix crypt はソルトを使用
owasp.org :ソルトを追加する理由
openwall.com :塩
免責事項:
私はセキュリティの専門家ではありません。(この回答はThomas Porninによってレビューされましたが)
セキュリティの専門家が何か問題を見つけた場合は、コメントするか、この wiki の回答を編集してください。