237

パスワードへのソルトの目的を理解するのに苦労しています。主な用途は、レインボー テーブル アタックを妨害することだと理解しています。ただし、これを実装するために私が見た方法は、問題を実際に難しくしているようには見えません。

ソルトを次のように使用することを提案する多くのチュートリアルを見てきました。

$hash =  md5($salt.$password)

これは、ハッシュが元のパスワードではなく、パスワードとソルトの組み合わせにマップされるようになったためです。しかし、$salt=foo$password=bar言う$hash=3858f62230ac3c915f300c664312c63f。これで、レインボー テーブルを持つ誰かがハッシュを逆にして、入力 "foobar" を思いつくことができます。次に、パスワードのすべての組み合わせ (f、fo、foo、... oobar、obar、bar、ar、ar) を試すことができます。パスワードを取得するのにさらに数ミリ秒かかる場合がありますが、それ以外はそれほど時間はかかりません。

私が見た他の使用法は、私の Linux システムです。/etc/shadow では、ハッシュ化されたパスワードは実際にはソルトとともに保存されます。たとえば、"foo" のソルトと "bar" のパスワードは、次のようにハッシュされます$1$foo$te5SBM.7C25fFDu6bIRbX1te5SBM.7C25fFDu6bIRbXハッカーがどうにかしてこのファイルを手に入れることができたとしても、の逆ハッシュには「foo」が含まれていることが知られているため、salt の目的はわかりません。

誰もがこれに当てることができる光をありがとう。

編集:助けてくれてありがとう。私が理解していることを要約すると、ソルトはハッシュ化されたパスワードをより複雑にするため、事前に計算されたレインボー テーブルに存在する可能性がはるかに低くなります。私が以前誤解していたのは、すべてのハッシュに対してレインボー テーブルが存在すると想定していたことです。

4

10 に答える 10

258

単一のパスワードをクラックする場合、パブリック ソルトによって辞書攻撃が難しくなることはありません。ご指摘のとおり、攻撃者はハッシュ化されたパスワードとソルトの両方にアクセスできるため、辞書攻撃を実行する場合、既知のソルトを使用してパスワードをクラックしようとするだけです。

パブリック ソルトは 2 つのことを行います。パスワードの膨大なリストをクラックするのに時間がかかるようにすることと、レインボー テーブルの使用を不可能にすることです。

最初のものを理解するには、何百ものユーザー名とパスワードを含む単一のパスワード ファイルを想像してください。ソルトがなければ、「md5(attempt[0])」を計算し、ファイルをスキャンして、そのハッシュがどこかに表示されるかどうかを確認できます。ソルトが存在する場合、「md5(salt[a] . attempts[0])」を計算し、エントリ A と比較してから、「md5(salt[b] . attempts[0])」を計算し、エントリ B と比較する必要があります。など。ファイルに含まれるユーザー名とパスワードの数はn何倍にもなります。n

2 つ目を理解するには、レインボー テーブルとは何かを理解する必要があります。レインボー テーブルは、一般的に使用されるパスワードに対して事前に計算されたハッシュの大きなリストです。ソルトのないパスワード ファイルをもう一度想像してみてください。私がしなければならないことは、ファイルの各行を調べ、ハッシュ化されたパスワードを取り出し、それをレインボー テーブルで調べることだけです。単一のハッシュを計算する必要はありません。ルックアップがハッシュ関数よりもかなり高速である場合 (おそらくそうです)、ファイルのクラッキングが大幅に高速化されます。

ただし、パスワード ファイルがソルト化されている場合、レインボー テーブルには事前にハッシュされた "salt . password" が含まれている必要があります。ソルトが十分にランダムである場合、これはほとんどありません。一般的に使用される、事前にハッシュされたパスワードのリスト (レインボー テーブル) には、おそらく "hello" や "foobar" や "qwerty" などを含めることになりますが、"jX95psDZhello" や「LPgB0sdgxfoobar」または「dZVUABJtqwerty」は事前に計算されています。そうなると、レインボー テーブルが法外に大きくなります。

したがって、ソルトは攻撃者を試行ごとに行ごとに 1 回の計算に減らします。これは、十分に長く、十分にランダムなパスワードと組み合わせると、(一般的に言えば) 解読できなくなります。

于 2009-01-07T16:50:10.820 に答える
122

他の回答は、トピックに関するあなたの誤解に対処していないようです。

塩の2つの異なる用途

ソルトを次のように使用することを提案する多くのチュートリアルを見てきました。

$hash = md5($salt.$password)

[...]

私が見た他の使用法は、私の Linux システムです。/etc/shadow では、ハッシュ化されたパスワードは実際にはソルトとともに保存されます。

パスワードデータベースに対してユーザーが入力したものを検証するには、入力をソルトと組み合わせてハッシュし、保存されたハッシュと比較する必要があるため、常にソルトをパスワードとともに保存する必要があります。

ハッシュのセキュリティ

これで、レインボー テーブルを持つ誰かがハッシュを逆にして、入力 "foobar" を思いつくことができます。

[...]

te5SBM.7C25fFDu6bIRbX の逆ハッシュには「foo」が含まれていることがわかっているためです。

ハッシュ自体を元に戻すことはできません (少なくとも理論上は)。「foo」のハッシュと「saltfoo」のハッシュには共通点はありません。暗号化ハッシュ関数の入力で 1 ビットでも変更すると、出力が完全に変更されます。

これは、一般的なパスワードを使用してレインボー テーブルを作成し、後でソルトで「更新」することができないことを意味します。最初から塩分を考慮する必要があります。

これが、そもそもレインボーテーブルが必要な理由です。ハッシュからパスワードを取得することはできないため、使用される可能性が最も高いパスワードのすべてのハッシュを事前に計算してから、ハッシュとそれらのハッシュを比較します。

塩の質

しかし言う$salt=foo

「foo」は、塩の選択としては非常に不適切です。通常は、ASCII でエンコードされたランダムな値を使用します。

また、各パスワードには独自のソルトがあり、システム上の他のすべてのソルトとは (うまくいけば) 異なります。つまり、攻撃者は、ハッシュの 1 つがデータベース内の値の 1 つと一致することを期待するのではなく、各パスワードを個別に攻撃する必要があります

攻撃

ハッカーがどうにかしてこのファイルを手に入れることができたとしても、塩が何の役に立つのかわかりません。

レインボー テーブル攻撃は常に必要/etc/passwdです (または、使用されているパスワード データベース)。そうでなければ、レインボー テーブルのハッシュと実際のパスワードのハッシュをどのように比較しますか?

目的としては、攻撃者が一般的に使用される 100,000 の英単語と典型的なパスワード (「秘密」と考えてください) のレインボー テーブルを作成したいとします。ソルトがなければ、彼女は 100,000 ハッシュを事前計算する必要があります。従来の 2 文字の UNIX ソルト (それぞれが 64 の選択肢の 1 つです[a–zA–Z0–9./]:) を使用しても、4,096,000,000 のハッシュを計算して保存する必要があります... かなりの改善です。

于 2009-01-07T17:06:20.227 に答える
88

ソルトのアイデアは、通常の文字ベースのパスワードよりも総当たりで推測するのをはるかに困難にすることです. レインボー テーブルは、多くの場合、特別な文字セットを念頭に置いて構築されており、すべての可能な組み合わせが含まれているとは限りません (可能ですが)。

したがって、適切なソルト値は、ランダムな 128 ビット以上の整数になります。これが、レインボー テーブル攻撃が失敗する原因です。保存されたパスワードごとに異なるソルト値を使用することで、1 つの特定のソルト値用に構築されたレインボー テーブル (単一のソルト値を持つ一般的なシステムの場合に発生する可能性があります) がすべてにアクセスできるわけではありません。一度にパスワード。

于 2009-01-07T15:59:47.773 に答える
37

多くの非常に思慮深い回答がある、さらに別の素晴らしい質問です-SOに+1!

明示的に言及されていない小さなポイントの 1 つは、各パスワードにランダムなソルトを追加することで、たまたま同じパスワードを選択した 2 人のユーザーが異なるハッシュを生成することを事実上保証していることです。

何でこれが大切ですか?

米国北西部の大手ソフトウェア会社のパスワード データベースを想像してみてください。30,000 のエントリがあり、そのうち 500 のパスワードがbluescreenであるとします。さらに、ハッカーがユーザーから IT 部門への電子メールを読んで、このパスワードを取得できたとします。パスワードがソルト化されていない場合、ハッカーはデータベースでハッシュ値を見つけ、それをパターン マッチするだけで他の 499 アカウントにアクセスできます。

パスワードをソルトすることで、500 個のアカウントのそれぞれが一意の (ソルト + パスワード) を持つことが保証され、それぞれに異なるハッシュが生成されるため、侵害が 1 つのアカウントに減少します。そして、あらゆる可能性に反して、電子メール メッセージに平文のパスワードを書き込むほど素朴なユーザーが、次期 OS 用の文書化されていない API にアクセスできないことを祈りましょう。

于 2009-01-10T16:30:37.857 に答える
15

ソルトを適用する良い方法を探していたところ、サンプル コードを含む次の優れた記事を見つけました。

http://crackstation.net/hashing-security.htm

著者は、ユーザーごとにランダムなソルトを使用することをお勧めします。これにより、ソルトにアクセスしても、ハッシュのリスト全体が簡単にクラックされることはありません。

パスワードを保存するには:

  • CSPRNG を使用してロング ランダム ソルトを生成します。
  • パスワードの先頭にソルトを追加し、SHA256 などの標準の暗号化ハッシュ関数でハッシュします。
  • ソルトとハッシュの両方をユーザーのデータベース レコードに保存します。

パスワードを検証するには:

  • データベースからユーザーのソルトとハッシュを取得します。
  • 指定されたパスワードの前にソルトを追加し、同じハッシュ関数を使用してハッシュします。
  • 指定されたパスワードのハッシュをデータベースのハッシュと比較します。一致する場合、パスワードは正しいです。そうでない場合、パスワードが正しくありません。
于 2012-07-13T19:18:17.090 に答える
10

ハッシュベースの暗号化を破るほとんどの方法は、ブルートフォース攻撃に依存しています。レインボー攻撃は本質的により効率的な辞書攻撃であり、低コストのデジタルストレージを使用して、ハッシュへの可能なパスワードの実質的なサブセットのマップを作成し、逆マッピングを容易にするように設計されています。この種の攻撃は、多くのパスワードがかなり短いか、単語ベースの形式のいくつかのパターンの1つを使用する傾向があるために機能します。

このような攻撃は、パスワードにさらに多くの文字が含まれていて、一般的な単語ベースの形式に準拠していない場合には効果がありません。最初に強力なパスワードを持っているユーザーは、このスタイルの攻撃に対して脆弱ではありません。残念ながら、多くの人は適切なパスワードを選択していません。ただし、妥協点があります。ランダムなジャンクを追加することで、ユーザーのパスワードを改善できます。そのため、「hunter2」の代わりに、パスワードを効果的に「hunter2908!fld2R75 {R7 /; 508PEzoz ^ U430」にすることができます。これは、はるかに強力なパスワードです。ただし、この追加のパスワードコンポーネントを保存する必要があるため、より強力な複合パスワードの有効性が低下します。結局のところ、このようなスキームには、弱いパスワードであっても、各パスワードに正味のメリットがあります。同じ事前計算されたハッシュ/レインボーテーブルに対して脆弱ではなくなりました。代わりに、各パスワードハッシュエントリは、一意のハッシュテーブルに対してのみ脆弱です。

パスワード強度の要件が弱いサイトがあるとします。パスワードソルトをまったく使用しない場合、ハッシュは事前に計算されたハッシュテーブルに対して脆弱であるため、ハッシュにアクセスできる人は、大部分のユーザーのパスワードにアクセスできます(ただし、多くのユーザーが脆弱なパスワードを使用します。かなりの割合)。一定のパスワードソルトを使用すると、事前に計算されたハッシュテーブルは価値がなくなるため、誰かがそのソルトのカスタムハッシュテーブルを計算するために時間を費やす必要がありますが、段階的に計算することもできます。問題空間の。最も脆弱なパスワード(たとえば、単純な単語ベースのパスワード、非常に短い英数字のパスワード)は数時間または数日で解読され、脆弱性の低いパスワードは数週間または数か月後に解読されます。時間が経つにつれて、攻撃者は増え続けるユーザーの割合のパスワードにアクセスできるようになります。すべてのパスワードに一意のソルトを使用する場合、これらの脆弱なパスワードのそれぞれにアクセスするのに数日または数か月かかります。

ご覧のとおり、無塩から一定の塩、固有の塩にステップアップすると、各ステップで脆弱なパスワードを解読するために数桁の増加が必要になります。ソルトがないと、ユーザーの最も弱いパスワードに簡単にアクセスできます。一定のソルトを使用すると、決心した攻撃者がこれらの弱いパスワードにアクセスできます。独自のソルトを使用すると、パスワードにアクセスするコストが非常に高くなるため、最も意欲的な攻撃者だけがアクセスできます。脆弱なパスワードのごく一部になりますが、多大な費用がかかります。

これがまさにその状況です。不適切なパスワードの選択からユーザーを完全に保護することはできませんが、ユーザーのパスワードを危険にさらすコストを、1人のユーザーのパスワードを危険にさらすほどの高額なレベルまで引き上げることはできます。

于 2009-01-08T00:21:31.160 に答える
-2

PHP --- md5() 関数、および $ の前に変数 --- を使用していると仮定します。それなら、この記事Shadow Password HOWTO特に 11 番目の段落を見てみてください。

また、メッセージ ダイジェスト アルゴリズムを使用することを恐れている場合は、mcryptモジュールによって提供されるものなどの実際の暗号アルゴリズム、またはmhashモジュール (sha1、sha256、およびその他)。

より強力なメッセージ ダイジェスト アルゴリズムが必要だと思います。MD5 と SHA1 には衝突の問題があることが知られています。

于 2009-01-07T16:26:09.887 に答える