更新:私は最近 この質問 から学びました、以下の議論全体で、私(そして他の人もそうだったと確信しています)は少し混乱しています:私はRainbowテーブルを呼んでいるものは実際にはハッシュ表。レインボーテーブルはより複雑なクリーチャーであり、実際にはヘルマンハッシュチェーンのバリアントです。答えはまだ同じだと思いますが(暗号解読に至っていないため)、議論の一部は少し歪んでいるかもしれません。
質問:「 Rainbowテーブルとは何で、どのように使用されますか?
通常、暗号化に強いランダム値をソルトとして使用し、Rainbow Table攻撃から保護するなど、ハッシュ関数(パスワードなど)で使用することを常にお勧めします。
しかし実際には、ソルトをランダムにするために暗号的に必要ですか?この点で、一意の値(ユーザーごとに一意、たとえばuserId)で十分ですか?実際には、システム内のすべての(またはほとんどの)パスワードを解読するために単一のRainbow Tableを使用することを防ぎます...
しかし、エントロピーの欠如は、ハッシュ関数の暗号強度を本当に弱めますか?
注:なぜsaltを使用するのか、それを保護する方法(必要ではない)、単一の定数ハッシュを使用する(使用しない)、または使用するハッシュ関数の種類については質問していません。
塩にエントロピーが必要かどうかだけです。
これまでのすべての回答に感謝しますが、(少し)あまり馴染みのない分野に焦点を当てたいと思います。主に暗号解析への影響-暗号数学のPoVから何らかの情報をお持ちの方がいれば幸いです。
また、考慮されていない追加のベクトルがある場合、それも素晴らしい入力です(複数のシステムの@Dave Sherohmanポイントを参照)。
それ以外に、理論、アイデア、またはベストプラクティスがある場合は、証拠、攻撃シナリオ、または経験的証拠のいずれかでこれをバックアップしてください。または、許容可能なトレードオフの有効な考慮事項です。このテーマに関するベストプラクティス(資本B資本P)に精通しているので、これが実際に提供する価値を証明したいと思います。
編集:ここでいくつかの本当に良い答えが、私は@Daveが言うように、それは一般的なユーザー名のためのレインボーテーブルに来ると思います...そして、あまり一般的でない名前も可能性があります。ただし、ユーザー名がグローバルに一意である場合はどうなりますか?私のシステムにとって必ずしも一意ではありませんが、各ユーザーごとに-たとえば電子メールアドレス。
1人のユーザーに対してRTを構築するインセンティブはありません(@Daveが強調したように、ソルトは秘密に保たれません)、これはまだクラスタリングを防ぎます。問題のみ私は別のサイトに同じメールとパスワードを持っているかもしれませんが、塩はとにかくそれを防ぎません。
それで、暗号解読に戻ります-IS必要なエントロピーかどうか?(暗号解読の観点からは必要ではないが、その他の実用的な理由。)
ソルトは伝統的にハッシュされたパスワードのプレフィックスとして保存されます。これにより、パスワードハッシュにアクセスできるすべての攻撃者に既に知られています。ユーザー名をソルトとして使用しても使用しなくても、その知識には影響しないため、単一システムのセキュリティには影響しません。
ただし、ユーザー名またはその他のユーザー制御値をソルトとして使用すると、システム間のセキュリティが低下します。同じパスワードハッシュアルゴリズムを使用する複数のシステムで同じユーザー名とパスワードを持っているユーザーは、同じパスワードハッシュで終わるためそれらの各システム。攻撃者として、アカウントを侵害する他の手段を試みる前に、ターゲットアカウントが他のシステムで最初に使用したことが知られているパスワードを試すため、これを重大な責任とは見なしません。同一のハッシュは、既知のパスワードが機能することを事前に教えてくれるだけで、実際の攻撃を簡単にすることはありません。 (ただし、アカウントデータベースをすばやく比較すると、優先度の高いターゲットのリストが表示されることに注意してください。これは、パスワードを再利用しているかどうかを教えてくれるためです。)
この考えからのより大きな危険は、ユーザー名が一般的に再利用されることです-あなたが訪問したいと思うどんなサイトでも、たとえば「Dave」という名前のユーザーアカウントを持ち、「admin」または「root」はさらに一般的です-これらの共通名を持つユーザーをターゲットとするRainbowテーブルの構築が、はるかに簡単かつ効果的になりました。
これらの欠陥は両方とも、ハッシュする前に2番目のソルト値(固定および非表示、または標準ソルトのように公開)をパスワードに追加することで効果的に対処できますが、その時点で、代わりに標準エントロピーソルトを使用することもできますユーザー名を使用します。
編集して追加:多くの人がエントロピーと塩のエントロピーが重要かどうかについて話している。それはそうですが、それについてのコメントのほとんどは考えているようです。
一般的な考え方は、エントロピーが重要であるため、攻撃者が塩を推測するのが困難になるようです。これは誤りであり、実際、完全に無関係です。さまざまな人から何度か指摘されているように、saltの影響を受ける攻撃はパスワードデータベースを持っている人だけが行うことができ、パスワードデータベースを持っている人は各アカウントのsaltを確認することができます。推測可能かどうかは、いつでも簡単に調べることができます。
エントロピーが重要である理由は、ソルト値のクラスタリングを避けるためです。 saltがユーザー名に基づいており、ほとんどのシステムに「root」または「admin」という名前のアカウントがあることがわかっている場合、これら2つのsaltのRainbowテーブルを作成すると、ほとんどのシステムがクラックされます。一方、ランダムな16ビットのソルトが使用され、ランダムな値がほぼ均等に分布している場合、2 ^ 16個の可能なソルトすべてに対してレインボーテーブルが必要です。
攻撃者が個々のアカウントの塩が何であるかを知ることを防ぐことではなく、潜在的な標的のかなりの割合で使用される単一の塩の大きな脂肪標的を彼らに与えないことです。
パスワードを安全に保存するには、高エントロピーソルトの使用が絶対に必要です。
ユーザー名「gs」を取得し、パスワードに追加します「MyPassword」はgsMyPasswordを提供します。ユーザー名が十分なエントロピーを取得していない場合、特にユーザー名が短い場合は、この値がレインボーテーブルに既に格納されている可能性があるため、レインボーテーブルを使用すると簡単に壊れます。
別の問題は、ユーザーが2つ以上のサービスに参加していることを知っている攻撃です。一般的なユーザー名はたくさんありますが、おそらく最も重要なユーザー名はadminとrootです。誰かが最も一般的なユーザー名で塩を含むレインボーテーブルを作成した場合、彼はそれらを使用してアカウントを侵害することができます。
以前は12ビットのソルトを使用していた 。 12ビットは4096通りの組み合わせです。 最近では多くの情報を簡単に保存できる であるため、これは十分に安全ではありませんでした。同じことは、最も使用される4096個のユーザー名にも当てはまります。一部のユーザーは、最も一般的なユーザー名に属するユーザー名を選択する可能性があります。
私はこれを見つけました password checker これはパスワードのエントロピーを計算します。 (ユーザー名を使用するなど)パスワードのエントロピーを小さくすると、レインボーテーブルが発生しやすくなるため、少なくともエントロピーの低いすべてのパスワードをカバーしようとするため、レインボーテーブルがはるかに簡単になります。
ユーザーが異なるWebサイト間でユーザー名を共有する可能性があるため、ユーザー名だけで問題が生じる可能性があるのは事実です。ただし、ユーザーが各Webサイトで異なる名前を持っている場合は、かなり問題はないはずです。それで、なぜ各ウェブサイトでそれをユニークにしないのですか。このようなパスワードをハッシュします
hashfunction( "www.yourpage.com /" + username + "/" + password)
これで問題が解決するはずです。私は暗号解読の達人ではありませんが、高いエントロピーを使用しないという事実がハッシュをより弱くすることを疑います。
私は両方を使用するのが好きです:高エントロピーのランダムなレコードごとのソルトと、レコード自体の一意のID。
これは辞書攻撃などに対するセキュリティにはあまり影響しませんが、パスワードを自分のものに置き換える意図で誰かが自分のソルトとハッシュをコピーするフリンジケースを削除します。
(確かにこれが当てはまる状況を考えるのは難しいですが、セキュリティに関してはベルトやブレースに害はありません。)
ソルトがパスワードごとに異なる限り、おそらく大丈夫だと思います。塩のポイントは、データベース内のすべてのパスワードを解決するために標準のRainbowテーブルを使用できないようにすることです。したがって、すべてのパスワードに異なるソルトを適用すると(ランダムではない場合でも)、パスワードごとに異なるソルトを使用するため、攻撃者は基本的にパスワードごとに新しいRainbowテーブルを計算する必要があります。
この場合の攻撃者はすでにデータベースを持っていると想定されているため、より多くのエントロピーを持つソルトを使用してもあまり役に立ちません。ハッシュを再作成できるようにする必要があるため、ソルトが何であるかをすでに知っている必要があります。とにかく、ソルト、またはソルトを構成する値をファイルに保存する必要があります。 Linuxのようなシステムでは、ソルトを取得する方法が知られているため、秘密のソルトを使用しても意味がありません。あなたはあなたのハッシュ値を持っている攻撃者がおそらくあなたのソルト値も知っていると仮定しなければなりません。
ハッシュ関数の強度は、その入力によって決定されません!
攻撃者に知られているソルトを使用すると、明らかにレインボーテーブル(特にrootのようなハードコーディングされたユーザー名の場合)の構築がより魅力的になりますが、hashを弱めることはありません。攻撃者が知らない塩を使用すると、システムの攻撃が難しくなります。
ユーザー名とパスワードの連結は、依然としてインテリジェントなレインボーテーブルのエントリを提供する可能性があるため、ハッシュされたパスワードで保存された一連の擬似ランダム文字のソルトを使用することは、おそらくより良いアイデアです。例として、ユーザー名「potato」とパスワード「beer」があった場合、ハッシュの連結入力は「potatobeer」であり、これはRainbowテーブルの妥当なエントリです。
ユーザーがパスワードを変更するたびにソルトを変更することは、妥当なパスワードポリシー(たとえば、大/小文字混合、句読点、最小長、n週間後の変更。
ただし、ダイジェストアルゴリズムの選択はより重要だと思います。たとえば、SHA-512の使用は、MD5よりもレインボーテーブルを生成する人にとっては苦痛であることがわかります。
塩が既知であるか、簡単に推測できる場合、辞書攻撃の難易度は増加していません。 「一定の」ソルトを考慮に入れた修正済みのRainbowテーブルを作成することもできます。
ユニークなソルトを使用すると、BULK辞書攻撃の難易度が上がります。
一意で暗号的に強力なソルト値を持つことが理想的です。
特定の入力値が複数回ハッシュされる場合、ソルトはできるだけ多くのエントロピーを持つ必要があります。結果のハッシュ値は、達成できる限り近く、常に異なるものになります。
可能な限り多くのエントロピーを持つソルト値をソルトで使用すると、ハッシュ(たとえば、パスワード+ソルト)の可能性がまったく異なるハッシュ値を生成することが保証されます。
ソルトのエントロピーが少ないほど、同じソルト値を生成する可能性が高くなり、同じハッシュ値を生成する可能性が高くなります。
入力が既知の場合はハッシュ値が「一定」であり、辞書攻撃やレインボーテーブルが非常に効果的になるのは「定数」であるという性質です。結果のハッシュ値を可能な限り変化させることにより(高いエントロピーソルト値を使用して)、同じinput + random-saltをハッシュすると、多くの異なるハッシュ値の結果が生成され、Rainbowテーブルを無効にします(少なくとも有効性を大幅に低下させます)攻撃。