私は、塩は単にレインボーテーブルが使用されるのを防ぐために使用されているといつも思っていました。アカウントごとに一意である必要があることを示唆する人もいます。現在、私はソルトとして使用する設定ファイルを使用しています。過去にmd5(salt + password)を実行しましたが、現在は.NETを使用しています PBKDF2 経由で(pass, salt_from_config)
。
私はこれを間違って行っているのですか、それともそれほど安全ではありませんか?ソルトは一意である必要がありますか、それとも予測不可能であるため、事前にレインボーテーブルを生成できませんか?
私はこれを説明する回答を 別の質問 に投稿しました。これは、パスワードの保存に関するすべての主要なセキュリティ問題の良い背景を提供するはずです。
あなたの質問にもっと直接答えるために-塩:
H(pass + username)
のようなスキームの問題は、攻撃者がソルトを知っていることです。したがって、単一のRainbowテーブルを使用してデータベース内のすべてのパスワードを解読する彼の能力はなくなりましたが、彼はcan主要なユーザーアカウント用のRainbowテーブルを作成します。これにより、特権ユーザーアカウント(adminなど)のRainbowテーブルを事前に計算し、データベースに違反するとすぐに使用することができます。
侵害に対処する時間がないため、これは問題です。攻撃について警告を受けてから数秒後、攻撃者は管理者アカウントにログインしました。攻撃者がパスワードをクラックすることを余儀なくされた場合after違反は、特権アカウントをロックダウンしてパスワードを変更する時間を与えます。
また、ソルト+ペッパースキームを検討することもできます。ペッパーは、データベースの外部に格納されている2番目のソルトです。コードで。これは、攻撃者がデータベースにしかアクセスできないSQLインジェクションモデルの攻撃を防ぐのに役立ちます。
ベストプラクティスは次のようなものです(唐辛子は省略してもかまいません)。
hash = KDF(pass + pepper, salt, workFactor)
どこ:
KDF
は、PBKDF2のbcryptなどの強力で遅い鍵導出関数です。pass
は強力なパスワードです(パスワードポリシーを適用してください!)pepper
は、コードに格納されている長いランダムな定数値です。salt
は、データベースにパスワードとともに保存される長いランダムな一意の値です。workFactor
は、ハードウェアとセキュリティの要件に適しています。ソルトはすべてのパスワードで一意である必要があります。
すべてのパスワードに同じソルトを使用している場合、攻撃者はその特定のソルトを使用してレインボーテーブルを生成し、データベース内のほとんどのパスワードを解読する可能性があります。
PBKDF2とGPUアクセラレーションに関するコメントに関して、これを指摘したいと思います link ここのSecurity.SEで、Thomas Porninが非常に優れた答えを出しました。
ソルトの正確な要件はパスワードハッシュアルゴリズムに依存しますが、通常の方法(bcrypt、PBKDF2 ...)の場合、only要件はソルトがユニーク。または、少なくとも実用的であるほどユニークです。頻繁に発生せず、外部から強制できない限り、奇妙な衝突は大きな問題ではありません。
独自性は世界的です。ソルトが特定のサーバーで一意であることは十分ではありません。同じハッシュアルゴリズムを使用する2つの異なるサーバーにも、異なるソルトが必要です。
世界中で一意であるための比較的一般的で安価な方法は、十分な長さ(ランダムな16バイトで十分)を使用して、暗号的に強力なPRNGからソルトを生成することです。それが bcrypt が行うことです。 PRNGが偏っている場合、一意性を実現するために少し長いソルトが必要です。PRNGがシードまたは内部状態が小さすぎるために弱い場合、その場合、その方法では一意性は十分に得られません。ユーザー名はない良い塩ですが、次の2つの理由があります。
塩は、keys(secretで、秘密にしておく必要があります)または初期化ベクトル(IVは一部のアルゴリズムの「開始点」であり、 CBC暗号化の場合の均一性や予測不可能性などの追加要件)。通常、ソルト値を渡すことには問題はありません。とにかく、パスワードからハッシュ値を再計算する人は誰でもソルトを知っている必要があります。したがって、ソルトの公開はファイルのパスワードベースの暗号化に固有です(ソルトはファイルヘッダーにエンコードされます)。また、クライアントでハッシュが発生する認証プロトコルで必ず公開されます(Javascriptが遅すぎるため、Webコンテキストでは非常にまれです)。不必要にソルトを公開しても意味はありませんが、ソルトを秘密にしてもセキュリティは実際には向上しません。
この答え では、フリンジシナリオが呼び出されます。攻撃者は事前にソルトを学習し、事前計算された大きなテーブルを準備してから、実際の攻撃を実行し、パスワードハッシュ。これは、攻撃者がパスワードを解読することを容易にするものではありません。実際、これにより彼の労力が増加します(パスワードが見つかったときに停止する代わりに完全なテーブルを作成する必要があるため、平均で2倍のコストになります。テーブルがRainbow説得である場合、テーブル生成のために追加の1.7係数が入力されます。保管費がかかります)。変更されるのはdynamicsです。これにより、侵入(ハッシュ値が盗まれます)からパスワードの回復までの時間が短縮されます。これはEdgeケースなので、発汗しないでください。ハッシュがサーバー側で発生する認証プロトコルでの保存にパスワードハッシュを使用する場合、ハッシュ値とともにソルトを保存するだけで、ソルトはハッシュ値自体と同じくらい機密性が高くなります。その他の場合(たとえば、パスワードベースのファイル暗号化)では、ソルトはより「公開」されますが、それは決して重要ではないので、ソルトを秘密に保つために余分な複雑さを追加しないでください(余分な複雑さは悪く、公共の塩よりも悪い)。