パスワードハッシュのランダムでないソルト


89

更新:私は最近この質問から以下の全体の議論で私(そして他の人もそうだったと確信しています)は少し混乱していることを学びました:私がレインボーテーブルと呼んでいるものは実際にはハッシュテーブルと呼ばれます。レインボーテーブルは、より複雑な生き物であり、実際にはヘルマンハッシュチェーンのバリアントです。解答は同じであると私は信じていますが(解読には至らないため)、一部の議論は少し歪んでいる可能性があります。
質問:「レインボーテーブルとは何ですか。どのように使用されますか?


通常、Rainbow Tableの攻撃から保護するなど、ハッシュ関数(パスワードなど)と共に使用するために、暗号として強力なランダム値をソルトとして使用することを常にお勧めします。

しかし、実際にはソルトがランダムであることは暗号的に必要ですか?これに関して、一意の値(userIdなどのユーザーごとに一意)で十分でしょうか?実際には、単一のRainbow Tableを使用してシステムのすべて(またはほとんど)のパスワードをクラックする
ことはできません... しかし、エントロピーの欠如は、ハッシュ関数の暗号強度を本当に弱めるのでしょうか?


ソルトを使用する理由、それを保護する方法(保護する必要はない)、単一の定数ハッシュを使用する(しない)、または使用するハッシュ関数の種類については尋ねていません。
塩がエントロピーを必要とするかどうかだけです。


これまでの回答に感謝しますが、私が(少し)あまり慣れていない領域に焦点を当てたいと思います。主に暗号解読への影響-誰かが暗号数学PoVから何らかの入力を持っている場合、私は最も感謝します。
また、考慮されていなかった追加のベクトルがある場合、それも素晴らしい入力です(複数のシステムでの@Dave Sherohmanポイントを参照)。
それ以上に、理論、アイデア、またはベストプラクティスがある場合は、証明、攻撃シナリオ、または経験的証拠のいずれかでこれをバックアップしてください。または、許容できるトレードオフについての有効な考慮事項...私はこのテーマのベストプラクティス(大文字のBの大文字P)に精通しています。これが実際に提供する価値を証明したいと思います。


編集:ここでいくつかの本当に良い答えがありますが、@ Daveが言うように、それは一般的なユーザー名のレインボーテーブルに帰着します...そしてあまり一般的ではない名前も考えられます。ただし、ユーザー名がグローバルに一意である場合はどうなりますか?必ずしも私のシステムで一意である必要はありませんが、ユーザーごとに-たとえば、電子メールアドレス。
(@Daveが強調しているように、saltは秘密にされていないため)シングルユーザー用のRTを作成するインセンティブはなく、これはクラスタリングを妨げます。唯一の問題は、別のサイトで同じメールアドレスとパスワードを使用している可能性があることです。
それで、それは暗号解読に帰着します-エントロピーは必要ですか、それとも不要ですか?(私の現在の考えでは、暗号解読の観点からは必要ではありませんが、他の実際的な理由からです。)


以下の答えの多くに混乱していると言わざるを得ません。ソルトを使用する主な目的は、レインボーテーブルの攻撃を防ぐことです。そのため、攻撃者はソルトごとにレインボーテーブルを再作成する必要があるため、ユーザー固有の操作を行う必要があります。私の2c。
ゴラン

塩が必要な場合など。サイトでは、URLにIDが含まれていることがよくあります。攻撃者がパスワードsaltがuserid + usernameであることを知っている(私たちが知っていると想定している)場合、salt値を回避するために攻撃を変更するのはかなり簡単です。
dmajkic 2009

@ dmajkic、saltは、RT攻撃を防ぎ、異なるユーザーに対して同じパスワードを区別することを目的としています。これは、ユーザー名であっても、当然です。
AviD 2009

@AviD:そうです。しかし、自分のパスのハッシュがわかっていて、saltが自分のユーザー名であることがわかっていれば、辞書の単語のハッシュパス値を簡単に作成して、他の誰かのパスハッシュと比較することができます。時間はユーザー名よりも優れている理由です。
dmajkic 2009

1
PHP Security ConsortiumのWebサイトで記事を見つけたところ、その例では、md5ハッシュ乱数をソルトとして 使用していますphpsec.org/articles/2005/password-hashing.html
helloworlder

回答:


156

Saltは伝統的にハッシュされたパスワードのプレフィックスとして保存されます。これにより、パスワードハッシュへのアクセス権を持つすべての攻撃者にそのことが知らされます。ユーザー名をsaltとして使用してもしなくても、その知識には影響しません。そのため、単一システムのセキュリティには影響しません。

ただし、ユーザー名またはその他のユーザー制御値をソルトとして使用すると、システム間セキュリティが低下します。同じパスワードハッシュアルゴリズムを使用する複数のシステムで同じユーザー名とパスワードを使用したユーザーは、同じパスワードハッシュをオンにするためです。それらのシステムのそれぞれ。私は攻撃者として、アカウントを侵害する他の手段を試みる前に、ターゲットアカウントが他のシステムで使用したことがわかっているパスワードを最初に試すので、これは重大な責任とは見なしません。同一のハッシュは、既知のパスワードが機能することを前もって教えてくれるだけであり、実際の攻撃を簡単にすることはありません。(ただし、アカウントデータベースをすばやく比較すると、誰がパスワードを再利用しているか、誰がパスワードを再利用していないかがわかるため、優先度の高いターゲットのリストが提供されます。)

このアイデアからのより大きな危険は、ユーザー名が一般的に再利用されることです-あなたが訪問したいサイトのほとんどが、たとえば「Dave」という名前のユーザーアカウントを持ち、「admin」または「root」がさらに一般的です-これにより、これらの一般的な名前を持つユーザーをターゲットとするレインボーテーブルの作成は、はるかに簡単で効果的です。

これらの欠陥は両方とも、ハッシュする前にパスワードに2番目のソルト値(標準ソルトのように固定または非表示または公開)を追加することで効果的に対処できますが、その時点では、代わりに標準エントロピーソルトを使用することもできます。ユーザー名をそこに組み込む方法。

追加のために編集: 多くの人々がエントロピーについて、そして塩のエントロピーが重要であるかどうかについて話しています。それはそうですが、それに関するほとんどのコメントが考えるように思われる理由ではありません。

一般的な考えでは、攻撃者が塩を推測するのは難しいため、エントロピーは重要であるようです。これは誤りであり、実際には完全に無関係です。さまざまな人が数回指摘したように、saltの影響を受ける攻撃は、パスワードデータベースを持っている人だけが行うことができ、パスワードデータベースを持っている人は、各アカウントのsaltを確認するだけです。推測できるかどうかは、簡単に調べることができる場合は問題になりません。

エントロピーが重要である理由は、ソルト値のクラスタリングを回避するためです。ソルトがユーザー名に基づいており、ほとんどのシステムに「root」または「admin」という名前のアカウントがあることがわかっている場合、これら2つのソルトのレインボーテーブルを作成すると、ほとんどのシステムがクラックされます。一方、ランダムな16ビットソルトが使用され、ランダムな値がほぼ均等に分布している場合、2 ^ 16の可能なすべてのソルトにレインボーテーブルが必要です。

それは、攻撃者が個々のアカウントのソルトが何であるかを知るのを防ぐことではなく、潜在的なターゲットのかなりの部分で使用される単一のソルトの大きくて太いターゲットを与えないことです。


同意した。ユーザー名の再利用に重点を置きます。ランダムなソルトを使用するシステムに対しては失敗する、ユーザー名をソルトとして使用する架空のシステムに対して攻撃が成功する可能性が最も高いためです。
スティーブジェソップ

システム間セキュリティに関するあなたの指摘に感謝します。また、将来的にはユーザー固有のレインボーテーブルが表示される可能性は低いと思います...
AviD

@AviD:そう思いますか?それはかなり特定の攻撃ベクトルです。
デビッドグラント

2
塩を生成するためではありません。ソルトの影響を受ける唯一の攻撃は、ハッシュされたパスワードに対して直接行われる攻撃です。塩が含まれているパスワードデータベースのコピーがない限り、攻撃でこの種の攻撃を行うことはできません。攻撃者はすでにソルトを所有しているため、基本的な(P)RNGが提供する同じソルトでハッシュされた複数のパスワードを回避するのに十分なエントロピーのみが必要です。
Dave Sherohman、2009

3
@ acidzombie24:すべてのパスワードに単一の固定ソルト(通常、私の経験では「ナンス」と呼ばれます)を使用すると、各パスワードに一意のランダムソルトを使用するよりも安全ではありません。同じパスワード。一方、nonceはデータベースではなくコードに格納される可能性が高いため、データベースのみを持つ攻撃者はnonceにアクセスできません。このため、最も安全なオプションは、システム全体のナンス(コードに格納)とパスワードごとのソルト(データベースに格納)の両方を使用することです。
Dave Sherohman、2011

29

パスワードを安全に保存するには、エントロピーの高いソルトを使用することが絶対に必要です。

ユーザー名「gs」を取得してパスワードに追加すると、「MyPassword」はgsMyPasswordになります。ユーザー名に十分なエントロピーがない場合、特にユーザー名が短い場合は、この値がすでにレインボーテーブルに格納されている可能性があるため、レインボーテーブルを使用すると簡単に壊れます。

もう1つの問題は、ユーザーが2つ以上のサービスに参加していることがわかっている攻撃です。一般的なユーザー名はたくさんありますが、おそらく最も重要なものはadminとrootです。誰かが最も一般的なユーザー名のソルトを含むレインボーテーブルを作成した場合、彼はそれらを使用してアカウントを侵害する可能性があります。

以前は12ビットのソルトを使用していました。12ビットは4096種類の組み合わせです。今日では、多くの情報を簡単に保存できるため安全性は十分ではありません。同じことが4096の最もよく使用されるユーザー名にも当てはまります。一部のユーザーは、最も一般的なユーザー名に属するユーザー名を選択する可能性があります。

あなたのパスワードのエントロピーを計算するこのパスワードチェッカーを見つけました。(ユーザー名を使用するなどして)パスワードのエントロピーを小さくすると、レインボーテーブルが発生する可能性が高くなるため、少なくともすべてのパスワードを低エントロピーでカバーしようとするため、レインボーテーブルがはるかに簡単になります。


良い点は+1です、あなた、潜在的に大規模なレインボーテーブルについて話していることになります。gsMyPasswordの長さのすべての値をカバーするには(大文字と小文字が混在する英数字を想定)、テーブルに36 ^ 12行が必要です!
デビッドグラント

補足として、分散レインボーテーブルプロジェクトには63,970個のクラックハッシュがありますが、36 ^ 12は4,738,381,338,321,616,896です!
デビッドグラント

おかげで、これは理にかなっています-しかし、PotatoHead氏が指摘したように、RTでクラックする合理的な可能性を超えて、まだスペースを拡大しています。また、ユーザー名が6〜8文字以上であると仮定すると、エントロピーが提供する追加の必要な値は何ですか?
AviD 2009

@Potato:可能なすべての英数字の組み合わせを含むレインボーテーブルを想定しています。これはそうである必要はありません。効果的なレインボーテーブルには、一般的なパスワード/ハッシュのハッシュが含まれます。ソルトは、辞書攻撃やレインボーテーブル/辞書の組み合わせから保護するためにあります。
ギヨーム

3
Windows上の「管理者」、* nixの上の「根」などMSSQL、中に「SA」:塩としてユーザー名を使用すると、予想どおりに命名高特権アカウントがあるシステムのための悪い考えです
誰も

8

ユーザーが異なるWebサイト間でユーザー名を共有する可能性があるため、ユーザー名だけでは問題が発生する可能性があるのは事実です。しかし、ユーザーが各Webサイトで異なる名前を持っている場合は、問題はありません。それでは、なぜそれを各Webサイトで一意にしないのか。このようなパスワードをハッシュする

ハッシュ関数( "www.yourpage.com/"+username+"/"+password)

これで問題が解決するはずです。私は暗号解読の達人ではありませんが、高いエントロピーを使用しないという事実がハッシュを弱くすることには疑いがあります。


これで十分だと思います。ただし、ハッシュは複雑な数学的フィールドであり、エントロピーの低い塩が将来的にハッシュを推測しやすくする可能性が非常に高い(特にハッシュが壊れた場合)ことを考えると、証明されたときにセキュリティに賭けることはしません。より安全なソリューションはそれほど高価ではありません。
GeorgSchölly11年

7

私は両方を使用するのが好きです:レコードごとの高エントロピーのランダムなソルトと、レコード自体の一意のID。

これにより、辞書攻撃などに対するセキュリティはそれほど向上しませんが、パスワードを自分のものに置き換えることを目的として、誰かがソルトとハッシュを別のレコードにコピーするというフリンジケースがなくなります。

(確かにこれが当てはまる状況を考えるのは難しいですが、セキュリティに関しては、ベルトやブレースに害はありません。)


パスワードをユーザーにバインドするアイデアが気に入っています。ただし、攻撃者がパスワードを変更できる場合、IDも変更できます。
GeorgSchölly2009

IDが何であるかに依存します。私はテーブルの主キーを使用しますが、これは自由に変更することはできません。TBH、ハッカーがデータベースに書き込んでいる場合、すでにかなり大きな問題に
直面し

3
いや、私はそれが好きです。攻撃者は多くの場合「内部関係者」です。私は彼の後にあるものがデータベースにないシナリオを思い描くことができますが、彼がデータベースの資格情報を上書きできる場合、彼は彼が望むことをするために自分自身を認証することができます。
エリクソン2009

1
いい視点ね。最初のユーザーを新しいデータベースに追加することがますます困難になっていることがわかります。アプリケーションを効果的に安全にして、ほとんどハッキングできないようにしました。[また、アプリケーション固有のソルトを使用して、あるデータベースから別のデータベースに認証情報をコピーできないようにします。]
teedyay

最後に私は誰かがこれを言っているのを見つけました:saltにユーザー固有の何かを追加します。これにより、侵入者が別のユーザーに資格情報をコピーすることを防ぎ、ハッカーがテーブルのハッシュフィールドとソルトフィールドに到達できた場合にパスワードを推測することを防ぎます。もう1つ私がやりたいことは、ハッシュで反復回数を使用しないことです。10Kまたは20Kのために行くのではなく、何かのよう19835.しないでください
アンドリュー

3

塩が既知であるか簡単に推測できる場合、辞書攻撃の難易度は増加していません。「一定の」ソルトを考慮に入れる、変更されたレインボーテーブルを作成することも可能です。

独自のソルトを使用すると、BULK辞書攻撃の難易度が上がります。

独自の暗号学的に強力なソルトバリューを持つことが理想的です。


2
レインボーテーブルの要点は、値が事前に生成されていること、および値(パスワードなど)に加えて、特定の定数のテーブルを生成している場合、それは完全に異なるテーブルであり、ハッシュ結果を直接試してください。:)
デビッドグラント

1
定数ハッシュは何の価値もありません。すべてのパスワードは、1つのレインボーテーブルを使用して解読できます。ソルトの目的は、レインボーテーブルを作成することが不可能であることです。
GeorgSchölly2009

1
@gs-一定の塩の効果を「含む」レインボーテーブルを作成できない理由がわかりません。攻撃領域(パスワード)は変更されないため、テーブルを拡張する必要はなく、再計算するだけです。
HUAGHAGUAH 2009

@Potato-トレードオフに依存します。会社の2万回のログインがすべて同じ定数ソルトでハッシュされている場合、個別にディクショナリ攻撃するよりも、新しいレインボーテーブルを計算する方が安上がりです。したがって、「BULK」を強調します。
HUAGHAGUAH 2009

3

各パスワードでソルトが異なる限り、おそらく大丈夫でしょう。ソルトのポイントは、標準のレインボーテーブルを使用してデータベース内のすべてのパスワードを解決できないことです。したがって、すべてのパスワードに異なるソルトを適用する場合(ランダムでなくても)、各パスワードは異なるソルトを使用するため、攻撃者は基本的に各パスワードに対して新しいレインボーテーブルを計算する必要があります。

この場合の攻撃者はすでにデータベースを持っていると想定されるため、よりエントロピーのあるソルトを使用しても、それほど効果はありません。ハッシュを再作成できる必要があるため、ソルトが何であるかをすでに知っている必要があります。したがって、ソルト、またはソルトを構成する値をファイルに保存する必要があります。Linuxのようなシステムでは、ソルトを取得する方法がわかっているため、秘密のソルトを使用しても意味がありません。あなたのハッシュ値を持っている攻撃者がおそらくあなたのソルト値も知っていると想定する必要があります。


3
「ソルトの要点は、標準のレインボーテーブルを使用してデータベース内のすべてのパスワードを解決できないことです。」同意しません。ポイントは、標準のレインボーテーブルを使用してパスワードを解決できないようにすることです。saltがユーザー名の場合、「root」のレインボーテーブルはrootのパスワードをクラックする可能性があります。
スティーブジェソップ

それはおそらく本当に重要な唯一のルールについてです。基本的に、パスワードはシステムで固有のものにする必要がありますが、それが何であるかは関係ありません。それでも、まだ簡単なことかもしれません。たくさんのエントロピーは必要ありません。
Kibbee

これも私の考えでしたが、「おそらく大丈夫」に行き詰まりました。私はまだこの理論が証明されているのを見ていません-または少なくとも暗号解読の影響がないことを確認しました。
AviD 2009

@onebyone:saltがユーザー名+定数のローカル値(多くの場合 ':'を使用)で構成されている場合、共通のユーザー名と共通の静的なsalt値を含むさまざまなRTがない限り、標準化されたRTはまだ台無しです。私はむしろそうではないと思います。
nsayer 2009

nsayerとともに。あなたは塩として、ユーザー名と一緒に#などのための事前生成RT、(D83d8、そこではないことを、システム全体の定数文字列を使用することができ、そしてそれはprobalby任意の虹のテーブルの攻撃を防止するであろう。
Kibbee

3

ハッシュ関数の強度は、その入力によって決定されません!

攻撃者に知られているソルトを使用すると、レインボーテーブル(特に、rootのようなハードコードされたユーザー名の場合)の作成が明らかに魅力的になりますが、ハッシュが弱まることはありません。攻撃者にとって未知のソルトを使用すると、システムが攻撃されにくくなります。

ユーザー名とパスワードを連結しても、インテリジェントなレインボーテーブルのエントリが提供される可能性があるため、ハッシュされたパスワードとともに保存された一連の疑似ランダム文字のソルトを使用することをお勧めします。例として、ユーザー名「ポテト」とパスワード「ビール」を持っている場合、ハッシュの連結入力は「ポテトビール」であり、これはレインボーテーブルの妥当なエントリです。

ユーザーがパスワードを変更するたびにソルトを変更すると、大文字と小文字の混在、句読点、最小の長さ、n週間後の変更など、合理的なパスワードポリシーの施行と同様に、長期的な攻撃を防ぐのに役立つ場合があります。

ただし、ダイジェストアルゴリズムの選択はより重要です。たとえば、MD5よりもレインボーテーブルを生成する方がSHA-512を使用するほうが苦痛であることが証明されます。


機能の強さは変わりませんが、出力は確実に変わります。入力が影響を受けるか既知である可能性がある場合、おそらくハッシュ値について何かが推測される可能性があります。それがリスクです。
マーティンカーペンター、

@Martin:一致するかどうかにかかわらず、ハッシュ値から推測できる唯一のこと!「roota」または「rootb」(「a」と「b」はパスワードを表す)をハッシュ関数に入れると、根本的に異なる出力が得られます。
デビッドグラント

塩は、レインボーテーブルを使用する攻撃者に知られています。
GeorgSchölly2009

サーバーは暗号化されていないソルトを知っている必要があります(ハッシュに照らしてパスワードをチェックするため)。このため、攻撃者がソルトにアクセスできることは当然のことと考えられ、非常に簡単に取得できます。
GeorgSchölly、2009

そうですね、それは与えられたものです-より具体的に言えば、私は暗号システム全体(またはハッシュ、サブシステム)の長所を意味しました。
AviD 2009

1

与えられた入力値が複数回ハッシュされた場合に得られるハッシュ値は、可能な限り近く、常に異なることを保証するために、ソルトはできるだけ多くのエントロピーを持つ必要があります。

常に変化するソルト値をソルトで可能な限り多くのエントロピーで使用すると、ハッシュ(たとえば、パスワード+ソルト)の可能性が完全に異なるハッシュ値を生成することが保証されます。

ソルトのエントロピーが少ないほど、同じソルト値を生成する可能性が高くなるため、同じハッシュ値を生成する可能性が高くなります。

入力がわかっている場合はハッシュ値が「一定」であり、「定数」であるため、辞書攻撃やレインボーテーブルが非常に効果的です。結果のハッシュ値を可能な限り変化させることにより(高いエントロピーソルト値を使用して)、同じ入力+ランダム塩をハッシュすると、多くの異なるハッシュ値の結果が生成され、それによってレインボーテーブルが無効になります(または、少なくとも効果が大幅に低下します)。攻撃。


繰り返しますが、私は単一の定数ソルト-むしろ非ランダムではなく、ユーザー固有の値の使用について言及していません。たとえば、userId。
AviD 2009

重要なのは、ソルト値が一定であってはならないということです。同じ「入力」値であるかどうかに関係なく、ハッシュするすべてのものは異なるソルトを持つ必要があります。Dave Sherohmanは、各ハッシュ計算で本質的に同じままであるユーザー固有の値を使用する場合の欠点についても説明しています。
CraigTP 2009

-1

エントロピーはソルト値のポイントです。

saltの背後に単純で再現可能な「数学」がある場合、saltが存在しない場合と同じです。時間の値を追加するだけで十分です。


このコメントは理解できません。あなたは「エントロピーを使う」と言ってから、「時間を使う」と言いますか?
マーティンカーペンター、

ユーザー名がソルトに使用されている場合、エントロピーは十分ではありません。しかし、ユーザー名+現在の日付を使用する場合-正確なソルトがいつ作成されたかを推測するのは難しいためです。
dmajkic 2009

「十分なエントロピー」は主観的です。それはあなたの標準です。この値を時間どおりに使用することは適切ではない場合があります。
マーティンカーペンター、

「絶対的な真のランダム性」というものはありません。それが「十分」であると言うのは私たちの責任です。この場合は時間が足りないと思うなら、他のものを使ってください。 stackoverflow.com/questions/84556/...
dmajkic

実際、ソルトのポイントは、(a)レインボーテーブル攻撃、および(b)同一のパスワード識別を防ぐために、各ハッシュ結果を一意にすることです。問題は、仮に仮にエントロピーが他に何のために必要なのかということです。
AVID
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.