ハッシュのために塩を隠す必要性
-
03-07-2019 - |
質問
職場では、2つの競合する塩の理論があります。私が取り組んでいる製品では、ユーザー名や電話番号などを使用してハッシュをソルトしています。基本的にはユーザーごとに異なるものですが、すぐに利用できるものです。他の製品は、ユーザーごとにランダムにソルトを生成し、ユーザーがパスワードを変更するたびに変更します。次に、塩はデータベースで暗号化されます。
私の質問は、2番目のアプローチが本当に必要かどうかです。純粋に理論的な観点からは、最初のアプローチよりも安全であることがわかりますが、実用性の観点からはどうでしょう。現在、ユーザーを認証するには、ソルトを暗号化せずにログイン情報に適用する必要があります。
それについて考えた後、私はこのアプローチによる本当のセキュリティ上の利益を見ることはありません。ソルトをアカウントからアカウントに変更すると、攻撃者が各アカウントの内容をすばやく判断する方法を知っていたとしても、ハッシュアルゴリズムをブルートフォースしようとすることは非常に困難になります。これは、パスワードが十分に強力であると仮定しています。 (明らかに、すべて2桁のパスワードのセットに対して正しいハッシュを見つけることは、8桁のパスワードの正しいハッシュを見つけるよりもはるかに簡単です)。私の論理が間違っていますか、それとも私が見逃しているものがありますか?
編集:さて、ここに、塩を暗号化することが本当に意味がないと思う理由があります。 (私が正しい軌道に乗っているかどうかは分かっています)。
次の説明では、パスワードは常に8文字、ソルトは5、すべてのパスワードは小文字で構成されていると仮定します(計算が簡単になります)。
エントリごとに異なるソルトがあるということは、同じレインボーテーブルを使用できないことを意味します(実際には、十分なサイズのテーブルがあれば技術的には可能ですが、現時点では無視しましょう)。これは、私が理解していることから塩の本当の鍵です。なぜなら、すべてのアカウントをクラックするには、それぞれについて話すために車輪を再発明する必要があるからです。ハッシュを生成するためにパスワードに正しいソルトを適用する方法を知っていれば、ソルトは実際にハッシュされたフレーズの長さ/複雑さを拡張するだけなので、それを行うでしょう。そのため、「知る」ために生成する必要のある可能な組み合わせの数を削減します。ソルトとは何かを知っているので、パスワードとソルトは13 ^ 26〜8 ^ 26です。これで簡単になりましたが、それでも本当に大変です。
ソルトの暗号化。ソルトが暗号化されていることがわかっている場合は、最初にそれを復号化しようとはしません(十分なレベルの暗号化があることがわかっている場合)。私はそれを無視します。前の例に戻って、復号化の方法を考え出す代わりに、13 ^ 26のすべてのキーを含む大きなレインボーテーブルを生成します。ソルトを知らないと間違いなく私は遅くなりますが、ソルトの暗号化を最初に解読しようとする記念碑的なタスクが追加されるとは思いません。だから、それだけの価値があるとは思わない。思考?
ブルートフォース攻撃でパスワードが保持される期間を説明するリンクは次のとおりです。 http://www.lockdown.co.uk/?pg=combi
解決
ここでの答えは、あなたが本当に保護しようとしているものを自問することです。誰かがあなたのデータベースにアクセスできる場合、暗号化されたソルトにアクセスでき、おそらくあなたのコードにもアクセスできます。それで暗号化されたソルトを解読できましたか?もしそうなら、暗号化はとにかくほとんど役に立たない。塩は本当にそれを作るためにそこにあるので、それが壊れた場合、一度にパスワードデータベース全体をクラックするレインボーテーブルを形成することはできません。その観点から、各ソルトが一意である限り違いはありませんが、ソルトまたはパスワードごとの暗号化されたソルトを個別にブルートフォース攻撃する必要があります。
他のヒント
塩を隠す必要はありません。
ハッシュごとに異なるソルトを使用する必要があります。実際には、暗号品質の乱数ジェネレータから8バイト以上を取得することで、これを簡単に実現できます。
私の以前の回答から:
Saltは、事前に計算された辞書攻撃を阻止するのに役立ちます。
攻撃者がありそうなパスワードのリストを持っているとします。彼はそれぞれハッシュできます 被害者のパスワードのハッシュと比較して、 一致します。リストが大きい場合、これには長い時間がかかる可能性があります。彼はしません 次のターゲットにその時間を費やしたいので、結果を記録します 「辞書」でハッシュは、対応する入力を指します。もし パスワードのリストは非常に長いため、次のようなテクニックを使用できます。 スペースを節約するためのレインボーテーブル。
ただし、次のターゲットがパスワードをソルト化したとします。たとえ 攻撃者は塩が何であるかを知っており、彼の事前計算されたテーブルは 役に立たない—ソルトは各パスワードから生じるハッシュを変更します。彼 リスト内のすべてのパスワードを再ハッシュし、ターゲットの 入力にソルトします。塩ごとに異なるものが必要です 辞書、そして十分な塩が使用されている場合、攻撃者は部屋を持っていません それらすべての辞書を保存します。時間を節約するための取引スペースはありません 長いオプション;攻撃者は各パスワードのハッシュにフォールバックする必要があります 彼が攻撃したい各ターゲットのリストで。
したがって、塩を秘密にする必要はありません。確実に 攻撃者はそれに対応する事前に計算された辞書を持っていません 特定の塩で十分です。
これについてもう少し考えた後、塩が隠されていると思うように自分をだますのは危険であることに気付きました。塩は隠せないと想定し、それにもかかわらずシステムが安全になるように設計する方がはるかに優れています。別の詳細な説明をで提供します答えます。
「塩」についての私の理解それはクラッキングをより難しくしますが、余分なデータを隠そうとしません。 saltを「秘密」にしてセキュリティを強化しようとしている場合は、暗号化キーにもっと多くのビットが必要になります。
2番目のアプローチは、ほんの少しだけ安全です。ソルトは、辞書攻撃やレインボーテーブル攻撃からユーザーを保護します。野心的な攻撃者がシステム全体を侵害することを難しくしますが、それでもシステムの1人のユーザーに焦点を当てた攻撃に対して脆弱です。電話番号などの一般に公開されている情報を使用し、攻撃者がこれに気付いた場合 、攻撃の一歩を保存しました。もちろん、攻撃者がデータベース全体、ソルト、その他すべてを取得するかどうかは問題です。
編集:この回答といくつかのコメントを読み直した後、混乱の一部は、非常に具体的な2つだけを比較しているという事実に起因することがあります質問で提示されたケース:ランダムソルトと非ランダムソルト。攻撃者がデータベース全体を取得する場合、電話番号をソルトとして使用するという質問は意味がありません。ソルトを使用するという質問ではありません。
これは、各ハッシュに同じソルトを持つことがなぜ悪いのかを示す簡単な例です
次の表を検討してください
UserId UserName, Password
1 Fred Hash1 = Sha(Salt1+Password1)
2 Ted Hash2 = Sha(Salt2+Password2)
salt 1がsalt2と同じ場合のケース1 Hash2がHash1に置き換えられた場合、ユーザー2はユーザー1のパスワードでログオンできます
塩1が同じ塩2ではない場合のケース2 Hash2がHash1に置き換えられた場合、user2はユーザー1のパスワードでログオンできません。
...ハッシュをソルトするユーザー名や電話番号のようなもの。 ...
私の質問は、2番目のアプローチが本当に必要かどうかです。純粋に理論的な観点からは、最初のアプローチよりも安全であることがわかりますが、実用性の観点からはどうですか
実用的な観点から、ソルトは実装の詳細です。ユーザー情報の収集または管理方法を変更した場合–正確な例を使用するために、ユーザー名と電話番号の両方が変更される場合があります–その後、セキュリティが侵害された可能性があります。このような外向きの変更に、より深いセキュリティ上の懸念を持たせたいですか?
各アカウントが電話番号を持っているという要件を停止するには、それらのアカウントがセキュリティ侵害にさらされていないことを確認するために、完全なセキュリティレビューを行う必要がありますか?
目標が異なる2つの手法があります:
-
「塩」 2つの異なるパスワードを別々に暗号化するために使用されます。この方法では、侵入者は暗号化されたパスワードのリスト全体に対して辞書攻撃を効率的に使用できません。
-
(共有)" secret"メッセージをハッシュする前に追加されるため、侵入者は自分のメッセージを作成して受け入れられません。
私は塩を隠す傾向があります。パスワードをハッシュする前に、パスワードの先頭に1〜1024の乱数を追加することにより、10ビットのソルトを使用します。ユーザーが入力したパスワードとハッシュを比較するとき、1から1024までループし、一致が見つかるまで、saltのすべての可能な値を試します。これには1/10秒未満かかります。 PHP password_hash および password_verify 。私の例では、「コスト」は10ビットのソルトに対して10です。または、別のユーザーが言った「隠された「塩」」から「ペッパー」と呼ばれます。データベースではソルトは暗号化されません。強引に強制されます。ハッシュを1000倍大きくするには、レインボーテーブルが必要になります。 sha256を使用するのは、高速ですが、それでも安全だと考えられているためです。
本当に、データを保護しようとしている攻撃の種類によって異なります。
各パスワードに固有のソルトの目的は、パスワードデータベース全体に対する辞書攻撃を防ぐことです。
パスワードごとに一意のソルトを暗号化すると、個々のパスワードを解読するのが難しくなりますが、実際に多くのメリットがあるかどうかを検討する必要があります。攻撃者がブルートフォースによって次の文字列を見つけた場合:
Marianne2ae85fb5d
DBに保存されているハッシュにハッシュします。どの部分がパスで、どの部分がソルトであるかを判断するのは本当に難しいですか?