パスワードソルトはレインボーテーブル攻撃に対してどのように役立ちますか?


220

パスワードへのソルトの目的を理解するのに問題があります。主な用途はレインボーテーブル攻撃を阻止することであることは私の理解です。ただし、これを実装するために私が見たメソッドは、問題を実際に難しくするようには見えません。

私はソルトを次のように使用することを示唆する多くのチュートリアルを見てきました:

$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.7C25fFDu6bIRbX1。ハッカーがなんとかしてこのファイルを入手できたとしても、のリバースハッシュにte5SBM.7C25fFDu6bIRbXは "foo"が含まれていることがわかっているため、ソルトの目的はわかりません。

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

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



そして、以下を参照してください。stackoverflow.com/questions/1645161/...
Jacco

また、ここで更新されました。md5ハッシュの使用は、もはやベストプラクティスではありません。stackoverflow.com/questions/12724935/salt-and-passwords
StuartLC

編集ありがとうございます。私は今はっきりしている同じ疑問を持っていました。したがって、「ソルト」のポイントは、実際には、レインボーテーブルに偽装(ソルト)パスワードのハッシュを最初から含めないようにすることです。:D
Vaibhav

回答:


237

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

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

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

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

しかし、パスワードファイルがソルト処理されている場合、レインボーテーブルには "salt。password"が事前にハッシュされている必要があります。塩が十分にランダムである場合、これは非常にまれです。よく使用される、事前にハッシュ化されたパスワードのリスト(レインボーテーブル)には、「hello」、「foobar」、「qwerty」などの項目が含まれますが、「jX95psDZhello」や「LPgB0sdgxfoobar」または「dZVUABJtqwerty」は事前に計算されています。それでは、レインボーテーブルが非常に大きくなります。

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


15
彼らがそうであったことを暗示するために私の答えで何を言ったかわかりませんか?
ロス

2
エリクソン、私は編集が混乱していたと思います-ほとんどの人はレインボーテーブル攻撃を一種の辞書攻撃とは考えていません。私の答えで混乱していると思われる具体的なことがあれば、私に知らせてください。私はそれを修正しようとします。
ロス

私は1つ以上の賛成票を与えられることを願っています!特に最初の段落について。それはすべての私見を要約します
Cesar

5
これは古いのですが、レインボーテーブルの説明が間違っています。代わりにハッシュテーブルについて説明しています。レインボーテーブルについては、security.stackexchange.com / questions / 379 /…を参照してください。ハッシュテーブルには、パスワードとハッシュの1対1のマッピング(説明したとおり)がありますが、レインボーテーブルには、ハッシュをプレーンテキストに変換し、何千回も再ハッシュして、最初のプレーンテキストと最終ハッシュのみを格納するリダクション関数が必要です。検索はハッシュテーブルよりも計算的に長くなりますが、ハッシュごとに多くのプレーンテキストを「キャプチャ」します。
マークフィッシャー

1
この答えは、ソルトを使用しない(特定のユーザーのパスワードハッシュの作成にバインドされている)と、これらのパスワードを格納する複数のテーブルでさえ、重複したパスワードが公開されるという事実を見落とします。最低でも、ユーザーが再利用するパスワードを特定できますが、さらに悪いことに、さまざまなデータベースで、さまざまな人が使用するパスワードを特定することもできます。
Maarten Bodewes 2017年

119

他の答えはあなたのトピックの誤解に対処していないようですので、ここに行きます:

塩の2つの異なる使用法

私はソルトを次のように使用することを示唆する多くのチュートリアルを見てきました:

$hash = md5($salt.$password)

[...]

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

あなたはいつもそれがハッシュ、ユーザーが自分のパスワードデータベースに対して入力したものを検証するために、あなたは塩で入力を結合する必要があるため、パスワードと塩を保管しなければならず、保存されたハッシュと比較します。

ハッシュのセキュリティ

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

[...]

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

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

つまり、共通のパスワードを使用してレインボーテーブルを作成し、後でソルトで「更新」することはできません。最初から塩を考慮する必要があります。

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

塩の品質

しかし言う $salt=foo

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

また、各パスワードには独自のソルトがあり、システム上の他のすべてのソルトと(できれば)異なります。この手段は、攻撃者がいることを期待したの個別代わりに、各パスワードを攻撃しなければならないことを1ハッシュのが彼女のデータベース内の値のいずれかに一致します。

攻撃

ハッカーがどういうわけかこのファイルを手に入れることができたとしても、塩がどんな目的を果たしているのかわかりません。

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

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


2
本当にいい答えです。それは私が物事をとてもよく理解するのに役立ちました。+1
wcm 2009

ハッカーがソルトにアクセスでき、それがハッシュ関数でどのように使用されたのか、それを使用してソルトハッシュのテーブルを生成し、それらのハッシュをレインボーテーブルと比較できないのではないでしょうか。
Jonny、

5
@ジョニーには「塩」はありません。重要なのは、ソルトはパスワードエントリごとに異なるということです。

86

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

したがって、適切なソルト値は、ランダムな128ビット以上の整数になります。これが、レインボーテーブル攻撃の失敗の原因です。保存されているパスワードごとに異なるソルト値を使用することにより、特定のソルト値用に作成されたレインボーテーブル(単一のソルト値を持つ一般的なシステムの場合など)がすべてにアクセスできないことも保証します一度にパスワード。


1
+1:Saltは、乱数ジェネレーターによって作成されたランダム文字列の16進数ダイジェストの一部である場合があります。各ビットはランダムです。
S.Lott、2009年

5
「レインボーテーブルは、ストレージスペースを節約するためにある程度の速度をあきらめる辞書攻撃の1つの形式です。」-実際にはその逆です。すべての可能な値を再ハッシュする時間を節約するために、優れたレインボーテーブルは保存にGBを引き継ぐことができます。
AviD 2009

2
同意-@erickson、私はあなたの編集がそこで間違っていると思います。虹のテーブルには、必要と巨大なストレージの量を、それは速く、ハッシュの背後にあるメッセージを取得することができます。
Carl Seleborg、

3
まあ、あなたはどちらも正しいです。標準の辞書攻撃と比較すると、レインボーテーブルはストレージスペースを節約するために速度を犠牲にします。一方、ブルートフォース攻撃と比較すると、レインボーテーブルは(たくさんの)スペースを使用して速度を上げます。今日、レインボーテーブルは辞書とほぼ同義です...
Rasmus Faber

...攻撃ですが、辞書攻撃にレインボーテーブルは必要ありません。
Rasmus Faber

35

さらにもう1つのすばらしい質問です。非常に思慮深い答えがたくさんあります。+ 1からSO!

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

何でこれが大切ですか?

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

パスワードをソルトすることにより、500個のアカウントのそれぞれが一意(塩+パスワード)になり、それぞれに異なるハッシュが生成されるため、違反を1つのアカウントに減らすことができます。そして、すべての確率に対して、電子メールメッセージにプレーンテキストのパスワードを書き込むのに十分な世間知らずのユーザーが、次のOSの文書化されていないAPIにアクセスできないことを期待しましょう。


異なるパスワードを選択する2人のユーザーについても同じで、同じハッシュ化されたパスワードがデータベースに保存されている可能性があります。(役に立たない...私は知っている)
Ant

15

私は塩を適用するための良い方法を探していて、サンプルコードを含むこの優れた記事を見つけました:

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

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

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

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

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

  • データベースからユーザーのソルトとハッシュを取得します。
  • 指定されたパスワードにソルトを付加し、同じハッシュ関数を使用してハッシュします。
  • 指定されたパスワードのハッシュをデータベースからのハッシュと比較します。それらが一致する場合、パスワードは正しいです。それ以外の場合、パスワードは正しくありません。

3
Hashcatは、1台のPCを使用して、毎秒約170億回のソルト処理されたSHA256ハッシュを試すことができます。リンクされた記事の著者は、「パスワードの解読をより困難にする:低速ハッシュ関数」という見出しの下でこれについて話します。scrypt、bcrypt、およびPBKDF2は適切な選択であり、サーバーIMHOの余分なCPUサイクルに値する以上のものです。Argon2は現在のところ最先端技術ですが、他のものほどの戦闘テストは行われていません。
kgriffs

12

ソルトがレインボーテーブル攻撃を失敗させる理由は、nビットのソルトの場合、レインボーテーブルはソルトなしのテーブルサイズの2 ^ n倍でなければならないためです。

「foo」をソルトとして使用する例では、レインボーテーブルを1600万倍大きくすることができます。

カールの128ビットソルトの例を考えると、これによりテーブルが2 ^ 128倍になります-今ではそれが大きくなります-または、言い換えると、誰かがそのほど大きなポータブルストレージを使用するようになるまでにどのくらいかかりますか?


8
たとえ単一の電子を使用して少しを保存する場合でも、その容量のポータブルストレージが作成されるまでにはかなりの時間がかかります...銀河のポータブルを移動するソーラーシステムを検討しない限り。
エリクソン09年

10

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

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

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

ご覧のように、無塩から一定の塩、固有の塩にステップアップすると、各ステップで脆弱なパスワードを解読するために数桁の増加が必要になります。saltがないと、ユーザーの最も弱いパスワードに簡単にアクセスできます。saltが一定の場合、これらの弱いパスワードは特定の攻撃者がアクセスできます。一意のsaltを使用すると、パスワードにアクセスするコストが高くなり、最も信頼できる攻撃者だけがアクセスできるようになります。脆弱なパスワードのごく一部に、それから多大な費用をかけて。

これがまさに現状です。ユーザーを不適切なパスワードの選択から完全に保護することはできませんが、ユーザーのパスワードを侵害するコストを、1人のユーザーのパスワードを侵害するだけでも法外に高くつくレベルまで上げることができます。


3

ソルトの1つの目的は、事前に計算されたハッシュテーブルを無効にすることです。誰かが数百万の事前計算されたハッシュのリストを持っている場合、ハッシュとソルトを知っていても、テーブルで$ 1 $ foo $ te5SBM.7C25fFDu6bIRbX1を検索することはできません。彼らはまだそれを総当たりにする必要があります。

カールSが言及している別の目的は、ハッシュのリストの総当たりをより高価にすることです。(それらにすべての異なる塩を与える)

塩が公開されている場合でも、これらの両方の目的は達成されます。


1

私の知る限り、ソルトは辞書攻撃を困難にすることを目的としています。

多くの人が一見ランダムな文字列の代わりにパスワードに一般的な単語を使用することは既知の事実です。

したがって、ハッカーは、ブルートフォースだけを使用するのではなく、これを利用して自分の利点を得ることができます。彼はaaa、aab、aacなどのパスワードを検索しませんが、代わりに単語と一般的なパスワードを使用します(ロードオブザリングの名前など!;))

したがって、私のパスワードがレゴラスである場合、ハッカーはそれを試して「数回」の試行でそれを推測できます。ただし、パスワードをソルトしてfooLegolasにした場合、ハッシュは異なるため、辞書攻撃は失敗します。

お役に立てば幸いです。


-2

PHPを使用していると思います--- md5()関数と$が前に付いた変数---そして、この記事を見ることができます。Shadow Password HOWTO特に11番目の段落。

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.