ソルト文字列はどこに保存しますか?


250

データベースストレージのパスワードをハッシュするときは、常に適切なエントリごとのソルト文字列を使用しました。私のニーズのために、ソルトをハッシュされたパスワードの隣のDBに保存することは常にうまくいきました。

ただし、ソルトをデータベースとは別に保存することを推奨する人もいます。彼らの主張は、データベースが侵害された場合でも、攻撃者は特定のソルト文字列を考慮に入れてレインボーテーブルを作成し、一度に1つのアカウントをクラックすることができるというものです。このアカウントが管理者権限を持っている場合は、他のアカウントをクラックする必要はないかもしれません。

セキュリティの観点から、塩を別の場所に保管することは価値がありますか?サーバーコードとDBが同じマシン上にあるWebアプリケーションについて考えてみます。ソルトがそのマシンのフラットファイルに格納されている場合、データベースが危険にさらされている場合、ソルトファイルも同様に破損する可能性があります。

これに対する推奨される解決策はありますか?


9
攻撃者が入手できない塩を保存できる場所がある場合は、そこにもパスワードを保存する必要があります。しかし、なぜすべてのパスワードに異なるソルトを使用しないのですか?
jrockway 2009

8
彼はパスワードごとに異なるソルト、jrockwayを使用しています。
アンバー

9
あなたの塩の大きさはどれくらいですか?ソルトは、レインボーテーブルが事前に計算されている可能性がほとんどないような十分な大きさ(32ビット?)である必要があります。
M.ダドリー

@emddudley最近は64ビット整数をソルトとして使用する習慣がありましたが、長くすることができない理由はありません。
フリード09

10
PWDTKの作成者はsourceforge.net/projects/pwdtknetです。正直言って心配することはなく、saltをパスワードと同じDBに格納するだけです。とにかく、ソルトが攻撃者に知られていると常に想定する必要があります。そのため、ラージクリプトランダムソルトの使用と十分なキーストレッチ(PBKDF2の反復)の実行に焦点を当て、既知の1つのソルトに対してレインボーテーブルを1つでも作成することは不可能です。正直なところ、ソルトを別の場所に配置することで達成しようとしているのは「セキュリティによる障害」であり、別のサーバーなどがダウンする可能性があることを確認しても、通常は役に立ちません。
thashiznets 2013年

回答:


259

レインボーテーブルのポイントは、他のユーザーの計算時間を節約するために事前に作成され、まとめて分散されることです-レインボーテーブルを生成するのに、パスワードとソルトの組み合わせを直接クラックするのと同じくらい時間がかかります(なぜなら、レインボーテーブルを生成するときに実際に行われていることは、ハッシュをブルートフォースするための計算を事前に実行しているため、saltを知ることによって誰かが「レインボーテーブルを生成」できるという主張は偽です。

ソルトをユーザーごとに保存するのであれば、ソルトを別のファイルに保存しても意味がありません。ソルトの目的は、1つのレインボーテーブルがDBのすべてのパスワードを解読できないようにすることです。


17
同意した。ソルトを個別に保存することで保護している脅威モデルは、悪意のある方法でDB内のソルトに何らかの方法でアクセスできるユーザーですが、(DB内の)ハッシュはアクセスできません。そして、その人は、後でハッシュを見つけることができると想定して、事前にレインボーテーブルの計算を開始します。不可能ではありませんが、この単一の攻撃手段を防御するためのエンジニアリングの努力にも値しません。
トムリッター

素敵な投稿、私は同じことを考えていました。ユーザーあたりのソルトについて考えたことはありませんでした。アプリケーションサーバーによって読み込まれるXMLファイルとして保存されるソルトはどうですか?または、どういうわけかサーブレットにハードコードされていますか?
ジグザット2012

9
@Jigzat-ユーザーごとに個別のソルトがない場合、ソルティングは無意味です。saltのポイントは、ハッシュを解除することをユーザーパスワードごとに個別のタスクにすることです。それらすべての塩が同じである場合、そうではありません。
アンバー

3
@TomRitterだけではありません。すべてのパスワードが複雑であると想定します。一部の攻撃者はソルトとハッシュを取り、10,000の最も一般的なパスワードのみをチェックする可能性があります。そうすれば彼らはまともな数の人々を得るでしょう。ただし、saltにアクセスできない場合は、より安全なパスワードを持っているユーザーに似ています。さて、パスワードデータベースが盗まれてもソルトデータベースが安全に保たれる可能性はありますが、それは別の問題です。
chacham15 2013

@アンバー、TomRitterは正しいと思います。ソルトを個別に保存することは、攻撃者にブルートフォース攻撃を強制することと、より簡単な辞書攻撃との違いを意味します。塩がわかっている場合は、ミル辞書攻撃の実行中に追加することができます。100%ソルトを守ることができる場合は、同じソルトを使用して、攻撃者にすべてをブルートフォースで強制することができます(パスワードとして「パスワード」を使用するユーザーの場合でも)。しかし、あなたはあなたの塩を守ることができます...おそらくそうではありません。そのため、ハッシュの横に格納して障害点を減らし、より強力なパスワードルールを適用することもできます。
Ultratrunks

35

これについては少し異なる見方をします。

私は常に、salted-passwordハッシュと混合したsaltを保存します。

たとえば、ソルトの前半をパスワードのソルトハッシュの前に配置し、ソルトの後半をパスワードのソルトハッシュの後に配置します。アプリケーションはこの設計を認識しているため、このデータをフェッチして、saltおよびsalted-passwordハッシュを取得できます。

このアプローチの私の理論的根拠:

パスワード/ハッシュデータが危険にさらされて攻撃者の手に渡った場合、攻撃者はデータを見てもソルトが何であるかを知ることができません。この方法では、攻撃者はハッシュを照合するパスワードを取得するためにブルートフォース攻撃を実際に実行することはできません。なぜなら、攻撃者はハッシュを知ることができず、データのどの部分がソルトの一部であるかを知る方法がないためです。ソルトパスワードハッシュの一部(アプリケーションの認証ロジックを知らない場合

saltされたパスワードのハッシュがそのまま保存されている場合、ブルートフォース攻撃を実行して、saltされてハッシュされたときにsalted-passwordのハッシュと同じデータを生成するパスワードを取得できます。

ただし、たとえば、ソルトパスワードハッシュがそのまま保存されていても、先頭にランダムな1バイトが付加されていたとしても、この最初のバイトが破棄されることを攻撃者が認識していない限り、これにより難易度も高くなります。攻撃の。アプリケーションは、ユーザーの認証に使用されると、データの最初のバイトを破棄することを知っています。

これの結論

1)認証アプリケーションが使用するデータを正確な形式で保存しないでください。

2)可能であれば、セキュリティを強化するために認証ロジックを秘密にしてください。

さらに一歩進んでください。

アプリケーションの認証ロジックを秘密にしておくことができない場合、多くの人がデータがデータベースにどのように格納されるかを知っています。また、ソルトパスワードハッシュの前にソルトの一部を追加し、残りのソルトにソルトを付加して、ソルトパスワードハッシュをソルトと組み合わせて保存することにしたとします。

ランダムなソルトを生成するときに、ソルトされたパスワードのハッシュの前/後に保存するソルトの割合をランダムに決定することもできます。

たとえば、512バイトのランダムなソルトを生成します。saltをパスワードに追加し、salted-passwordのSHA-512ハッシュを取得します。また、ランダムな整数200を生成します。次に、saltの最初の200バイトを格納し、その後にsalted-passwordハッシュを格納し、その後にソルトの残りを格納します。

ユーザーのパスワード入力を認証するとき、アプリケーションは文字列を渡し、データの最初の1バイトがソルトの最初の1バイトであり、その後にソルトハッシュが続くと想定します。このパスは失敗します。アプリケーションは、データの最初の2バイトをソルトの最初の2バイトとして使用し続け、最初の200バイトをソルトの最初の200バイトとして使用した後、肯定的な結果が見つかるまで繰り返します。パスワードが間違っている場合、アプリケーションは何も見つからなくなるまですべての順列を試し続けます。

このアプローチの長所:

セキュリティの向上-認証ロジックがわかっている場合でも、正確なロジックはコンパイル時には不明です。正確なロジックの知識があっても、ブルートフォース攻撃を実行することは事実上不可能です。ソルトの長さを長くすると、セキュリティがさらに向上します。

このアプローチの短所:

正確なロジックは実行時に推測されるため、このアプローチは非常にCPUに負荷がかかります。ソルトの長さが長いほど、このアプローチはCPUに負荷がかかります。

不正なパスワードを認証すると、CPUコストが最も高くなります。これは正当な要求に対して逆効果になる可能性がありますが、攻撃者に対するセキュリティが向上します。

このアプローチはさまざまな方法で実装でき、可変幅のソルトやソルト付きパスワードのハッシュを使用することでさらに安全にすることができます。


9
あなたのアプローチでは、ハッシュプロセス(ソルトを適用するアルゴリズム)にシークレットを追加するだけです。この秘密は、塩にコショウを追加するとはるかに簡単に追加できます。チュートリアルでこれを指摘しました。BCryptのような最新のハッシュ関数は、各反復で元のソルトを使用して独自にソルトを適用するため、これを制御することはできません。
martinstoeckli 2013年

@martinstoeckli BCryptがソルトを独自に適用することは正しいですが、そのソルト+ハッシュの保存は開発者としてのあなた次第です。したがって、ソルト+ハッシュにペッパーを簡単に追加して、データベースに永続化できます。次に、その後の取得時に、データベースから値を読み取り、pepper値を取り除き、残りの値をBCryptに渡します。
PeterToTheThird 2013年

2
@PeterToTheThird-これはコショウの利点を無効にします。コショウはサーバー側のシークレットを追加し、それがシークレットを維持している間のみ機能します(塩とは逆)。典型的な攻撃はSQLインジェクションです。誰かがデータベースにはアクセスできるがコードにはアクセスできない場合、データベースに保存されているペッパーは役に立たなくなります。ほとんどのBCrypt実装は結果のハッシュ値にソルトを自動的に追加するため、この値にはすでにソルト、コスト係数、アルゴリズム、およびハッシュが含まれています。この文字列は、長さが60文字の単一のフィールドに格納できます。
martinstoeckli 2013年

さらに、BCryptなどの「キー強化」機能を使用する場合、ソルトの使用を制御できません。ただし、コショウを使用したい場合は、塩にコショウを追加し、ハッシュ関数への「塩」入力の代わりに「ペッパー塩」として使用します。「ペッパー」は、データベースに格納されていないが、認証コードに埋め込まれているか、別の安全な場所に格納されている適切なデータです。SHA-512を関数の例として一般的な観点から問題に取り組みましたが、BCryptなども同様に使用できます。
イブラヒーム2013年

2
@martinstoeckli-はい、実際の実装は、使用するハッシュ関数によって異なります。認証ロジックを実装するときは、明らかに、ハッシュ関数のパラメーターと出力を考慮する必要があります。結局のところ、pepperはハッシュ関数に導入されたもう1つの変数であり、saltやhashと同じ場所に格納されていません
イブラヒーム2013年

23

多くの場合、それらはハッシュの前に付加され、同じフィールドに格納されます。

それらを個別に保存する必要はありません。重要なのは、パスワードごとにランダムなソルトを使用して、1つのレインボーテーブルをパスワードハッシュのセット全体に対して使用できないようにすることです。ランダムソルトを使用すると、攻撃者は各ハッシュを個別にブルートフォースする必要があります(または可能なすべてのソルトのレインボーテーブルを計算します-はるかに多くの作業)。

より安全な保管場所がある場合は、ハッシュをそこに保管することは理にかなっています。


4
しかし、一致するソルトを含め、ハッシュされたすべてのパスワードが漏洩した場合はどうなりますか?それは同じくらい安全ではありませんか?
mghaoui

10
@mghaouiしかし、「パスワード」を知りたい場合は、一部のソルトが同じでない限り、ソルトごとにレインボーテーブルを作成する必要があります。
フランクリン

4

William PenberthyによるDeveloping ASP.NET MVC 4 Web Applicationsの本に基づく:

  1. 別のデータベースに保存されているソルトにアクセスするには、ハッカーが2つの異なるデータベースをハッキングしてソルトとソルトパスワードにアクセスする必要があります。それらをパスワードと同じテーブル、または同じデータベースの別のテーブルに保存すると、ハッカーがデータベースにアクセスしたときに、ソルトとパスワードハッシュの両方にアクセスできるようになります。セキュリティには、システムへのハッキングのコストや時間がかかりすぎて価値がないプロセスが含まれるため、ハッカーが取得する必要があるアクセスの量を2倍にすることで、システムをより安全にすることができます。
  2. 使いやすさが、ソルトをハッシュされたパスワードと同じデータベースに保持する主な理由です。2つのデータベースが常に同時に利用可能であり、常に同期していることを確認する必要はありません。各ユーザーがランダム化されたソルトを持っている場合、ソルトを使用する利点は最小限です。ソルトを使用すると、個人のパスワードを簡単に見つけられる可能性がありますが、システム全体のパスワードを解読するために必要な力が大きくなるためです。このレベルの議論では、まさにそれが期待されていることです:パスワードを保護することです。ハッカーがデータベースのコピーを入手した場合、アプリケーションデータはすでに侵害されています。この時点での問題は、共有パスワードの可能性によるユーザーのリスクを軽減することです。
  3. 2つの別個のリンクされたデータベースを維持するための要件は広範囲にわたっています。確かに、それはセキュリティの認識を追加しますが、それが与える唯一の利点は、データの単一の要素であるパスワードを保護することです。データベースのすべてのフィールドが個別に暗号化され、そのために同じソルトが使用された場合、システムの基本的なセキュリティが強化されるため、データとは別に保存する方が理にかなっています。

ただし、アプリケーションが両方のデータベースを認証できる場合、攻撃者がアプリケーションコードを侵害した場合、それは1つのデータベースである場合と本質的に同じではありませんか?
John Ernest

0

ソルトのポイントは、すべてのレインボーテーブルを役に立たなくし、新しいセットを作成する必要があることです。 文字列を推測するのに、レインボーテーブルを作成するのと同じくらい時間がかかります。 たとえば、「パスワード」のSHA-256ハッシュは5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8です。"badpassword"などのソルトが追加された後、ハッシュされる新しい文字列は "passwordbadpassword"になります。これは、雪崩の影響により、出力が劇的に変化します457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6

通常、ソルトはパスワードと同じデータベースに格納されます。一方のデータベースがハッキングされた場合、もう一方のデータベースもハッキングされる可能性があるためです。

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