web-dev-qa-db-ja.com

ハッシュをソルトすることは、一般的な知識が意味するのと同じくらい安全ですか?

(このトピックを検索しましたが、それを解決する完全な質問/回答は見つかりませんでした。または、関連する可能性のある質問の適切な部分さえ見つかりませんでした。)

私は自分のWebページにユーザーパスワードのソルト関数を実装していますが、いくつか疑問があります。

ソルトは、パスワードに追加されてからハッシュされる拡張機能です。つまり、パスワードはhash(password+salt)としてデータベースに保存されます。しかし、どこに塩を保存しますか?塩は単にレインボーテーブルを「役に立たない」ようにすることですよね?

攻撃者はRainbowテーブルを作成し、すべてのハッシュを変換して塩を削除することはできませんか?結局のところ、ソルトはデータベースのどこかに保存されています。したがって、ハッシュされたパスワードを見つけることができれば、対応するソルトを見つけることができるはずです。 Saltはパスワードを長くするだけで、Rainbowテーブルをより長く実行するように思われます。

では、どのようにして塩の効果を最大化するのでしょうか?パスワードを動的に長くすることは別として、実際には複数のセキュリティ上の理由はありませんが、パスワードを文字列のビットに変換できます。

saltがどのように機能するかについての私の想定は正しいですか?そうでない場合、どのようにしてソルトとソルト付きパスワードを正しく保存する必要がありますか?

39

あなたは根本的に正しいのですが、それは単にパスワードを長くするだけですが、追加することがいくつかあります。また、平均的なパスワードはそれほど長くも安全でもありません。「無料」で長さを追加することはほとんどありません。ソルトは、攻撃者が「パスワード」を一度ハッシュしてから「パスワード」のパスワードを持つすべてのユーザーを探すことができないようにするためです。

代わりに、「password03j9834nfp-3028n408」と「passwordn0438wnvas89v5sne」のハッシュを生成する必要があります。これにより、安全でないパスワードを識別する保護が大幅に向上し、安全なパスワードを見つけることの困難さが増すというプラスの利点があります。

「攻撃者がRainbowテーブルを作成してから、すべてのハッシュを変換してソルトを削除することはできませんか?」ここにはいくつかの問題があります。

1つ目は衝突です。レインボーテーブルは、元の入力を生成することが保証されていません。目的の出力を生成したAN入力を生成することのみに関心があります。ソルトはユーザーが入力したものに追加されるため、攻撃者はハッシュに使用された正確な入力を見つける必要があります。

正確な入力を見つける必要があるため、衝突を利用するためのレインボーテーブルの利点は失われます。さらに、すべての可能な塩を総当たりにするのに必要なサイズは、ほとんどの攻撃者が保持するには大きすぎます。

また、元の入力が何であるかを理解せずに、ハッシュから単純にソルトを削除することもできません。特定のハッシュに対応するソルトで終わる値を探す必要があります。これにより、DB内のソルト値ごとに個別のレインボーテーブルを作成する必要があり、可能なソルトごとにレインボーテーブルを作成することは不可能であるため、事前計算の機能が無効になります。

26
AJ Henderson

あなたはレインボーテーブルがどのように機能するかについて根本的な誤解を持っています。

レインボーテーブルまたはハッシュテーブルは、攻撃者が攻撃の前に構築します。 _MD5_の7文字未満の文字列のすべてのハッシュを含むハッシュテーブルを作成するとします。データベースを危険にさらしてハッシュのリストを取得した場合、私がしなければならないのは、テーブルのハッシュを検索してパスワードを取得することだけです。

ソルトを使用すると、特定のアルゴリズムpriorの攻撃に対するRainbowテーブルを生成できません。ソルトは秘密である必要はありません。ハッシュと一緒にデータベースに保存します。

x = hash(salt+password)次に、それを_salt+x_の形式でデータベースに保存します。これにより、Rainbowテーブルとハッシュテーブルが役に立たなくなります。

いつものように自分でロールバックするのではなく、bcryptscryptまたは_pbkdf2_を使用して、ソルト処理を含むすべての詳細を処理します。参照 パスワードを安全にハッシュする方法?

53
user10211

A Rainbow table は、ブルートフォースによってハッシュを元に戻すための最適化です。これはトレードオフで機能します。巨大なデータ構造を構築するために多くの事前計算を行い、その後、多くのハッシュをすばやくクラックできます。

レインボーテーブルは、カバーするサーチスペースのクラックハッシュのみを支援します。具体的には、レインボーテーブルは、印刷可能な文字からなるプレーンテキスト用に作成されています。ソルトを追加する基本的な原則は、ハッシュされる平文にはパスワードとソルトの両方が含まれるということです。ソルトを追加すると、検索スペースは Rainbowテーブルを作成するには大きすぎます になります。

したがって、パスワードにソルトを追加することにより、多くのクラックに対するブルートフォース攻撃のコストを償却する方法はありません。攻撃者は、各ハッシュについてすべての作業を実行する必要があります。ソルトを知っている場合にのみ開始します。

ハッシュとソルトが与えられた場合、「ソルトを削除」する方法はありません。これはハッシュ関数の基本的なプロパティです。2つの文字列が関連していることがわかっていても(たとえば、パスワードがpassword + saltのサブストリングであることを知っている場合)、hash(password)を知っているhash(password)を見つけるのに役立ちません塩)。 攻撃者からソルトを隠す必要はありません :一意である必要があります(そして パスワードから派生していない )が、それ以上に秘密である必要はありませんハッシュ。 ( pepper と呼ばれる追加の秘密ソルトを追加できますが、これは限られた状況でのみ役立ちます。)

ハッシュをソルトすることは戦いの半分にすぎません。パスワードを安全にハッシュするもう1つの部分は、ハッシュ関数は検証者よりもクラッカーに大きな害を与えるため、低速でなければならないことです。 自分で転がしてはいけません 、専門家によって吟味された方法を使用してください。 bcrypt または PBKDF2 または scrypt を使用します。パスワードの保存を実装するには、暗号化を自分で行う必要はありません。ライブラリ関数を呼び出します。

パスワードのハッシュについて知りたいこと、パスワードのハッシュについて知りたくないこと、パスワードのハッシュについて知らないかもしれないことすべてについて、 パスワードを安全にハッシュする方法は? を読んでください。 =

独自のソルトが1つの問題を解決します。すべてのアカウントを1回のブルートフォース攻撃で同時に攻撃することはできません。

8文字の長さのすべての印刷可能なASCIIパスワードのRainbowテーブルを作成してみたとしましょう1。それは96です8 約720億(7.2 x 1015)可能性。 1秒あたり10億個のパスワードを生成するGPUを使用している場合、解読に約1か月ほどかかります(そして、kWあたり0.10ドルで200Wの場合、平均で約200ドルです。電気代としては最悪の場合は400ドル程度です)。

つまり、何らかのSQLインジェクションから、あるいは古いバックアップのハードドライブを見つけて、linkinのすべてのアカウントのハッシュを見つけます。たとえば、100万人のユーザーのハッシュがあります。無塩ハッシュの場合、1つのGPUで約400ドルの電力で2か月でこれらのハッシュの大部分を破壊できます。それらがすべて独自に塩漬けされていて、それらの数百万をすべて破壊したい場合、各固有の塩が独自の独立した攻撃を行う必要があるため、4億ドルの電力が必要になります。あなたが言う前に、私は塩を含む大きなレインボーテーブルを作成します。少なくとも、典型的な塩は5桁の16進文字(16 ** 5)であることを認識してください。テーブル(たとえば、あなたはそれを生成するために電気に4億ドルを費やす必要があります)。

次に、キー強化を追加して、ハッシュを1回実行する代わりに、プロセスをN回反復します(たとえば、3回の反復ハッシュ関数はhash(salt+hash(salt+hash(salt+pw)))になります)。これで、毎秒10億ハッシュを破ることができる代わりに、毎秒10億/ Nハッシュを破ることができるため、すべての攻撃のN倍の費用がかかります。 (通常のNは5000です。1つのハッシュを破るには約200万ドルの電力が必要です。超大規模Nの問題は、パスワードの試行を検証するためのサーバー上の計算リソースが多いことです)。

1 -これはパスワードを解読する最も効果的な方法ではありません。以前に使用された何百万ものパスワードの辞書リストは、多くのパスワードが非常に弱いため、はるかに効果的です。自分でパスワードを生成したり(通常は非常に低いエントロピー)、パスワードを再利用することはお勧めしません。 keepassxのようなサービスを使用して、サイトごとにランダムなパスワードを作成し、暗号化されたファイルに保存できます。キーの強化+独自のソルトは、最も単純なハッシュ以外のハッシュを試して壊すことが不可能であることを意味します。

9
dr jimbob

レインボーテーブルは、事前計算されたハッシュテーブルで、ハッシュを計算するよりもテーブルを検索する方がはるかに高速であるため、比較的短時間でパスワードを解読するために使用されます。

ハッシュされたパスワードを見つけることができれば、対応するソルトを見つけることができるはずです

攻撃者が単一のパスワードを解読しようとしても、攻撃者が知っているソルトは大きな問題にはなりません。ソルトはパスワードごとにソルトが異なるため、パスワードのリストを解読することは困難で時間がかかります。

しかし、どこに塩を保存しますか?塩は単にレインボーテーブルを「役に立たない」ようにすることですよね?

ソルトはDBにのみ保存され、パスワードごとにランダムなソルトが用意されています。はい、ソルトを使用すると、レインボーテーブルの使用が非常に困難になります。レインボーテーブルは通常、使用される一般的なパスワードを使用して作成されます。ランダムな塩を追加すると、レインボーテーブルでひびが入りにくくなります。

攻撃者はRainbowテーブルを作成し、すべてのハッシュを変換して塩を削除することはできませんか?

ハッシュから単純にソルトを削除することはできないため、既知のソルトを使用してレインボーテーブルを作成することを意味する可能性があります(実際の攻撃を実行する前)。 テーブルの再計算 は、既知のソルトをすべて考慮すると、テーブルのサイズが大きすぎるため、お勧めできません。スペースと時間のトレードオフを忘れないでください。一度に1つのソルトのテーブルを作成すると、エネルギーを浪費しすぎます。レインボーテーブルを作成する目的は、1つのパスワードではなく、パスワードリストを解読することです。

ソルトが提供するもう1つの非常に重要な値の追加はソルトが異なるため、2人のユーザーが同一のパスワードハッシュになることはありません。攻撃者がパスワードの1つをクラックでき、ソルトが使用されない場合、攻撃者はルックアップを実行して、他のどのユーザーが同じパスワードを使用しているかを確認する必要があると想像してください。

2
Shurmajee

まず、なぜWebページに低レベルの暗号コードを実装するのですか?これは解決された問題だと思います。ライブラリを使用するフレームワークを使用します。

次に、ハッシュは、ハッシュが漏洩した場合に備えてパスワードを保護します。あなたのサイトはパスワードデータベースへのアクセスを提供していないので、この状況は理想的には発生しないはずです。ソルトは、そのイベントでパスワードデータベース全体を保護するのに役立ちます。

攻撃者がそのデータベースの1つのパスワードに集中している場合、それほど大きな違いはありません。攻撃者がハッシュを検索してRainbowテーブルからパスワードを取得することができないという意味で、それは仕事を難しくします。ソルトを使用したパスワードのブルートフォーシングはわずかに遅くなります。これは、ハッシュされるバイトがさらに数バイト増えるため、ハッシュラウンドでマシンサイクルがさらに数サイクルかかるためです。

むかしむかし、パブリックアクセスを提供するUnixシステム(学生向けのキャンパスシステムなど)では、パスワードが左右に解読されていました。これが簡単である理由はさまざまですが、主な問題は単純なものでした。機密のパスワードハッシュ情報が、ユーザーに関する他の情報フィールドと同じファイルに保持されていて、そのファイル/etc/passwdが世界でした-読みやすい。修正は、機密情報を別のファイル/etc/shadowに入れることです。 Presto:これにより、システム上で権限のない正当なアカウントを持つスクリプトキディによるパスワードの解読が終了します。

同様に、あなたがパスワードを漏らさない限り、誰もあなたのパスワードを強引に強制することはありません。それらが漏洩し、誰かが特定のユーザーのパスワードを求めている場合、それらを阻止するためにできることはほとんどありません。

異なるシステムで同じパスワードを使用し、何年もパスワードを変更しないユーザーは、常に脆弱になります。塩、こしょう、ケチャップを加えることができます。違いはありません。

ソルトは、パスワードデータベース全体をクラックして、できるだけ多くの異なるパスワードを収集したいユーザーを阻止します。ソルトとは、事前に計算されたテーブルから単に取得するのではなく、各パスワードを個別に総当たりにする必要があることを意味します。ソルトにNビットがある場合、少なくとも理想的には、攻撃者のRainbowテーブルデータベースは2 ^ N倍大きくする必要があります。 32ビットのソルトは、パスワードを検索するだけで40億倍も大きいRainbowテーブルデータベースが必要であることを意味します。

サイトに20人のユーザーしかない場合は、もちろん最大20の異なるソルトしかありません。したがって、攻撃者が行うことは、パスワードディクショナリを取得し、それらのソルトを使用して20の異なる方法で各エントリをハッシュすることです。

そのため、ソルトはデータベースをRainbowテーブルルックアップから保護するだけでなく、ブルートフォースクラッキングから約Nの係数で保護します。Nはユーザー数です。 N個のパスワードをブルートフォースにするには、攻撃者はN倍の作業をブルートフォースとして行う必要があります。 (ソルトの幅が十分であると仮定します。少なくともNの2を底とする対数と同じ大きさです。ソルトの幅が12ビットしかない場合は、ユーザーの数に関係なく、4096の異なるソルトしか存在できません。)

塩がなければ、これは真実ではありません。同時に任意の数のパスワードをブルートフォースで強制することは、1つをブルートフォースで強制することと同じくらい簡単です。

1
Kaz

塩漬けにはいくつかの要因があり、そのうち少なくとも1つは欠けています。

  • 彼らはレインボーテーブルを役に立たなくします。誰かがパスワードデータベースを調べて、パスワードが「5f4dcc3b5aa765d61d8327deb882cf99」であることがわかった場合、「レインボーテーブル」を作成する必要さえありません。その値をグーグル検索するだけで、グーグルは「」のmd5ハッシュであることを教えてくれますパスワード"。パスワードがdbに入れられる前にハッシュされる場合、「レインボーテーブル」ルックアップメカニズムは役に立たなくなります。 Rainbowテーブルを役に立たなくするためにソルトをデータベースに保存する必要はありません。ソルトは常に「xxxx」またはその他の任意の文字列にすることができます。 6a316e1fdac8a61d9c7a2ed1cba4a804(「xxxxpassword」のmd5ハッシュ)をグーグル検索しても、結果は得られません。

  • 適切に実行された場合、ソルトは通常、侵入者がパスワードを解読するために両方データベースandコードを必要とすることを意味します。パスワードを "xxxx" + passwordまたはpw.substring(0,2)+ "xxxx" + pw.substring(2)としてハッシュすることができます。攻撃者もコードを盗んだ場合を除き、パスワードをどのようにソルトしたかはわかりません。 Webサーバーがデータベースと同じボックスで実行されていないことがよくあります。コンパイルされたプログラミング言語では、コードがWebサーバーでも使用できない場合があります。データベースに保存するソルトに関係なく、ハッシュの前にパスワードにさらに連結される長い任意の固定ソルトをデータベースの外部に保存することをお勧めします。

  • 独特の塩はクラッキングをより高価にします。他の誰かが指摘したように、静的ソルト( "xxxx")を使用して各辞書の単語をハッシュすると、パスワードデータベース全体をスキャンして "6a316e1fdac8a61d9c7a2ed1cba4a804"を探し、パスワードが "password"である人を探すことができます。各行が異なるソルトを使用する場合、N人のユーザーの1人がパスワード「password」を持っているかどうかを確認するためだけにN個のハッシュを実行する必要があります。

  • 2番目の点では、単一の固定単純塩のみを使用し、他の塩を使用しないように注意してください。クラッカーは、パスワードが「パスワード」である誰かが見つかるまで、任意の文字列+「パスワード」をハッシュしてみて、本質的にあなたのソルトを解読することができます。パスワードの大規模なデータベースでは、少なくとも1人のユーザーが、「password」などの簡単なパスワードを使用する必要があります。

0
Brian