web-dev-qa-db-ja.com

ハッシュのために塩を隠す必要性

職場では、2つの競合する塩の理論があります。私が取り組んでいる製品では、ユーザー名や電話番号などを使用してハッシュをソルトしています。基本的にはユーザーごとに異なるものですが、すぐに利用できるものです。他の製品は、ユーザーごとにランダムにソルトを生成し、ユーザーがパスワードを変更するたびに変更します。次に、塩はデータベースで暗号化されます。

私の質問は、2番目のアプローチが本当に必要かどうかです。純粋に理論的な観点からは、最初のアプローチよりも安全であることが理解できますが、実用性の観点からはどうでしょう。現在、ユーザーを認証するには、ソルトを暗号化せずにログイン情報に適用する必要があります。

それについて考えた後、私はこのアプローチから本当のセキュリティ上の利益を見ることはありません。アカウントからソルトを変更しても、攻撃者が各アカウントの内容をすばやく判断する方法を知っていたとしても、ハッシュアルゴリズムをブルートフォースしようとすることは非常に困難です。これは、パスワードが十分に強力であると仮定しています。 (明らかに、すべて2桁のパスワードのセットの正しいハッシュを見つけることは、8桁のパスワードの正しいハッシュを見つけるよりもはるかに簡単です)。私の論理が間違っていますか、それとも私が見逃しているものがありますか?

EDIT:わかりましたので、塩を暗号化することは本当に意味がないと思う理由はここにあります。 (私が正しい軌道に乗っているかどうかは分かりません)。

以下の説明では、パスワードは常に8文字で、saltは5で、すべてのパスワードは小文字で構成されていると仮定します(計算が簡単になるだけです)。

エントリごとに異なるソルトがあるということは、同じRainbowテーブルを使用できないことを意味します(実際には、十分なサイズのテーブルがあれば技術的には可能ですが、現時点では無視しましょう)。これは、私が理解していることから塩の真の鍵です。なぜなら、すべてのアカウントを解読するには、それぞれについて話すために車輪を再発明しなければならないからです。ハッシュを生成するためにパスワードに正しいソルトを適用する方法を知っている場合、ソルトは実際にハッシュされたフレーズの長さ/複雑さを拡張するだけなので、私はそれを行います。したがって、ソルトが何であるかを知っているので、パスワードとソルトを13 ^ 26から8 ^ 26に「知っている」ために生成する必要がある組み合わせの数を削減します。これで簡単になりましたが、それでも非常に困難です。

ソルトの暗号化に。ソルトが暗号化されていることがわかっている場合は、最初にそれを復号化しようとはしません(十分なレベルの暗号化があることがわかっている場合)。無視します。前の例に戻って、復号化の方法を考え出す代わりに、13 ^ 26のすべてのキーを含む大きなRainbowテーブルを生成します。ソルトを知らないと間違いなく私は遅くなりますが、ソルト暗号化を最初に解読しようとする記念碑的なタスクが追加されるとは思いません。だから、それだけの価値があるとは思わない。考え?

以下は、ブルートフォース攻撃でパスワードが保持される期間を説明するリンクです。 http://www.lockdown.co.uk/?pg=combi

96
kemiller2002

ここでの答えは、あなたが本当に何を保護しようとしているのかを自問することです。誰かがあなたのデータベースにアクセスできる場合、暗号化されたソルトにアクセスでき、おそらくあなたのコードにもアクセスできます。それで暗号化されたソルトを解読できますか?もしそうなら、暗号化はとにかくほとんど役に立たない。塩は本当にそれを作るためにあるので、レインボーテーブルを形成して、パスワードデータベースが壊れた場合に一度にあなたのパスワードデータベース全体をクラックすることはできません。その観点から、各ソルトが一意である限り違いはありませんが、ソルトまたは各パスワードの暗号化されたソルトを個別にブルートフォース攻撃する必要があります。

42
tloach

塩を隠す必要はありません。

ハッシュごとに異なるソルトを使用する必要があります。実際には、暗号品質の乱数ジェネレータから8バイト以上を取得することで、これを簡単に実現できます。

私の以前の答え から:

ソルトは、事前に計算された辞書攻撃を阻止するのに役立ちます。

攻撃者がありそうなパスワードのリストを持っているとします。彼はそれぞれをハッシュし、犠牲者のパスワードのハッシュと比較し、一致するかどうかを確認できます。リストが大きい場合、これには長い時間がかかる可能性があります。彼は次のターゲットにそれほど時間を費やしたくないので、ハッシュが対応する入力を指す「辞書」に結果を記録します。パスワードのリストが非常に長い場合は、レインボーテーブルなどの技術を使用してスペースを節約できます。

ただし、次のターゲットがパスワードをソルト化したとします。たとえ攻撃者がソルトを知っていたとしても、事前に計算されたテーブルは価値がありません。ソルトは各パスワードから生成されるハッシュを変更します。彼はリスト内のすべてのパスワードを再ハッシュし、ターゲットのソルトを入力に添付する必要があります。塩ごとに異なる辞書が必要であり、十分な塩が使用されている場合、攻撃者はそれらすべての辞書を保存する余地がありません。時間を節約するための取引スペースは、もは​​やオプションではありません。攻撃者は、攻撃したいターゲットごとにリスト内の各パスワードのハッシュにフォールバックする必要があります。

そのため、塩を秘密にする必要はありません。攻撃者がその特定のソルトに対応する事前に計算された辞書を持っていないことを確認するだけで十分です。


これについてもう少し考えた後、塩が隠されていると思うように自分をだますのは危険だと気づきました。塩は隠せないと想定し、それにもかかわらずシステムが安全になるように設計する方がはるかに優れています。より詳細な説明を提供します 別の回答で

94
erickson

隠れた塩はもはや塩ではありません。コショウです。用途があります。塩とは違います。

Pepperは、パスワードに追加された秘密キー+ saltで、ハッシュをHMAC(ハッシュベースのメッセージ認証コード)にします。ハッシュ出力とソルトにアクセスできるハッカーは、理論的にはブルートフォースでハッシュを生成する入力を推測できます(したがって、パスワードテキストボックスで検証に合格します)。コショウを追加することにより、暗号化されたランダムな方法で問題の領域を増やし、深刻なハードウェアなしで問題を扱いにくくします。

コショウの詳細については、 here を確認してください。

hmac も参照してください。

3
John Wu

「塩」の私の理解は、それがクラッキングをより困難にすることですが、余分なデータを隠そうとはしません。 saltを「秘密」にしてセキュリティを強化しようとしている場合は、暗号化キーにより多くのビットが必要になります。

3
gbarry

2番目のアプローチは、ほんの少しだけ安全です。ソルトは、ユーザーを辞書攻撃やレインボーテーブル攻撃から保護します。野心的な攻撃者がシステム全体を侵害することを難しくしますが、それでもシステムの1人のユーザーに焦点を当てた攻撃に対して脆弱です。電話番号などの公開されている情報を使用し、攻撃者がこれに気付いた場合、攻撃のステップを保存しました。 。もちろん、攻撃者がデータベース全体、ソルト、およびすべてを取得するかどうかは問題です。

編集:この回答とコメントの一部を読み直した後、混乱の一部は、私が提示した2つの非常に具体的なケースのみを比較しているという事実に起因する可能性があります質問:ランダムソルトと非ランダムソルト。 電話番号をソルトとして使用するという質問は、攻撃者がデータベース全体を取得する場合には意味がありませんnotまったく塩。

3
Bill the Lizard

...ハッシュをソルトするユーザー名または電話番号のようなもの。 ...

私の質問は、2番目のアプローチが本当に必要かどうかです。純粋に理論的な観点からは、最初のアプローチよりも安全であることがわかりますが、実用性の観点からはどうですか?

実用的な観点から、ソルトは実装の詳細です。正確な例を使用するために、ユーザー情報の収集方法や管理方法を変更したり、ユーザー名と電話番号の両方を変更したりすると、セキュリティが侵害された可能性があります。このような外向きの変更に、より深いセキュリティ上の懸念を持たせたいですか?

各アカウントが電話番号を持っているという要件を停止するために、それらのアカウントがセキュリティ侵害にさらされていないことを確認するための完全なセキュリティレビューが必要ですか?

2
Anon

各ハッシュに同じソルトを使用するのが悪い理由を示す簡単な例です

次の表を考慮してください

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

salt 1がsalt2と同じ場合のケース1 Hash2をHash1に置き換えた場合、ユーザー2はユーザー1のパスワードでログオンできます

salt 1が同じsalt2でない場合のケース2 Hash2をHash1に置き換えた場合、user2はユーザー1のパスワードでログオンできません。

2
Charles Faiga

目標が異なる2つの手法があります。

  • 「塩」は、それ以外は同じ2つのパスワードを別々に暗号化するために使用されます。この方法では、侵入者は暗号化されたパスワードのリスト全体に対して辞書攻撃を効率的に使用できません。

  • (共有)「秘密」はメッセージをハッシュする前に追加されるため、侵入者は自分のメッセージを作成して受け入れさせることはできません。

1
Javier

私は塩を隠す傾向があります。パスワードをハッシュする前に、パスワードの先頭に1〜1024の乱数を追加することにより、10ビットのソルトを使用します。ユーザーが入力したパスワードとハッシュを比較するとき、1から1024までループし、一致するものが見つかるまで可能な限りすべてのsaltの値を試します。これには1/10秒未満しかかかりません。 PHP password_hash および password_verify からこの方法で行うというアイデアを得ました。私の例では、 "cost"は10です。 10ビットのソルトまたは別のユーザーが言ったように、隠された「ソルト」は「ペッパー」と呼ばれます。ソルトはデータベースで暗号化されません。それは強引に強制されます。 。sha256は高速ですが、安全であると考えられているため、sha256を使用します。

0
Russell Hankins