314

保存する前にパスワードを 2 回ハッシュすることは、1 回ハッシュすることよりも多かれ少なかれ安全ですか?

私が話しているのは、これを行うことです:

$hashed_password = hash(hash($plaintext_password));

これだけの代わりに:

$hashed_password = hash($plaintext_password);

安全性が低い場合は、適切な説明 (またはリンク) を提供できますか?

また、使用するハッシュ関数によって違いはありますか? 同じハッシュ関数を繰り返す代わりに、(たとえば) md5 と sha1 を混ぜても違いはありますか?

注 1: 「ダブル ハッシュ」と言うときは、パスワードをよりわかりにくくするために、パスワードを 2 回ハッシュすることを指しています。衝突を解決するテクニックについて話しているのではありません。

注 2: 本当に安全にするには、ランダムなソルトを追加する必要があることはわかっています。問題は、同じアルゴリズムで 2 回ハッシュすることがハッシュに役立つか、それとも損なわれるかです。

4

16 に答える 16

283

パスワードを一度ハッシュするのは安全ではありません

いいえ、複数のハッシュはそれほど安全ではありません。これらは、安全なパスワードの使用に不可欠な部分です。

ハッシュを繰り返すと、攻撃者が候補リスト内の各パスワードを試すのにかかる時間が長くなります。パスワードの攻撃にかかる時間を数時間から数年に簡単に増やすことができます。

単純な反復では不十分です

ハッシュ出力を入力にチェーンするだけでは、セキュリティには不十分です。反復は、パスワードのエントロピーを保持するアルゴリズムのコンテキストで実行する必要があります。幸いなことに、設計に自信を与えるのに十分な精査が行われたいくつかの公開されたアルゴリズムがあります。

PBKDF2のような優れた鍵導出アルゴリズムは、ハッシュの各ラウンドにパスワードを挿入し、ハッシュ出力での衝突に関する懸念を軽減します。PBKDF2はそのままパスワード認証に使用できます。Bcryptは、暗号化ステップで鍵導出に従います。そうすれば、鍵導出を元に戻すための高速な方法が発見された場合でも、攻撃者は既知平文攻撃を完了する必要があります。

パスワードを破る方法

保存されたパスワードは、オフライン攻撃から保護する必要があります。パスワードがソルトされていない場合、事前に計算された辞書攻撃(たとえば、レインボーテーブルを使用)でパスワードが破られる可能性があります。それ以外の場合、攻撃者は時間をかけて各パスワードのハッシュを計算し、保存されているハッシュと一致するかどうかを確認する必要があります。

すべてのパスワードが同じように使用されるとは限りません。攻撃者はすべての短いパスワードを徹底的に検索する可能性がありますが、ブルートフォース攻撃の成功の可能性は、キャラクターが追加されるたびに急激に低下することを知っています。代わりに、最も可能性の高いパスワードの順序付きリストを使用します。それらは「password123」で始まり、使用頻度の低いパスワードに進みます。

攻撃者リストが長く、100億人の候補者がいるとしましょう。また、デスクトップシステムが1秒あたり100万のハッシュを計算できると仮定します。攻撃者は、1回の反復のみが使用された場合、リスト全体を3時間未満でテストできます。ただし、2000回の反復を使用した場合、その期間はほぼ8か月になります。より高度な攻撃者(たとえば、GPUの能力を利用できるプログラムをダウンロードできる攻撃者)を打ち負かすには、より多くの反復が必要です。

いくらで十分ですか?

使用する反復回数は、セキュリティとユーザーエクスペリエンスの間のトレードオフです。攻撃者が使用できる特殊なハードウェアは安価ですが、それでも1秒あたり数億回の反復を実行できます。攻撃者のシステムのパフォーマンスによって、何度も繰り返された場合にパスワードを破るのにかかる時間が決まります。ただし、アプリケーションでこの特殊なハードウェアを使用することはほとんどありません。ユーザーを悪化させることなく実行できる反復回数は、システムによって異なります

おそらく、認証中にユーザーにさらに3/4秒ほど待たせることができます。ターゲットプラットフォームのプロファイルを作成し、可能な限り多くの反復を使用します。私がテストしたプラットフォーム(モバイルデバイスの1人のユーザー、またはサーバープラットフォームの多くのユーザー)は、60,000〜120,000回の反復でPBKDF2を快適にサポートでき、コスト係数が12または13のbcryptをサポートできます。

その他の背景

ハッシュにおけるソルトと反復の役割に関する信頼できる情報については、PKCS#5をお読みください。PBKDF2はパスワードから暗号化キーを生成するためのものでしたが、パスワード認証の一方向ハッシュとしてはうまく機能します。bcryptの各反復は、SHA-2ハッシュよりもコストがかかるため、使用する反復を少なくすることができますが、考え方は同じです。Bcryptはまた、派生キーを使用して既知の平文を暗号化することにより、ほとんどのPBKDF2ベースのソリューションを超えた一歩を踏み出しました。結果の暗号文は、いくつかのメタデータとともに「ハッシュ」として保存されます。ただし、PBKDF2で同じことをするのを妨げるものは何もありません。

このトピックについて私が書いた他の回答は次のとおりです。

于 2008-12-07T21:44:54.033 に答える
53

はい、再ハッシュは検索スペースを削減しますが、いいえ、それは問題ではありません-効果的な削減は重要ではありません.

再ハッシュはブルート フォースにかかる時間を増やしますが、それを 2 回だけ行うのも最適ではありません。

本当に必要なのは、パスワードをPBKDF2でハッシュすることです。これは、salt と反復を使用して安全なハッシュを使用する実証済みの方法です。この SO レスポンスを確認してください。

編集:私はほとんど忘れていました-MD5を使用しないでください!!!! SHA-2 ファミリー (SHA-256、SHA-384、SHA-512) などの最新の暗号化ハッシュを使用します。

于 2008-12-07T23:49:15.017 に答える
10

はい - 文字列に一致する可能性のある文字列の数を減らします。

すでに述べたように、ソルトハッシュははるかに優れています.

ここの記事: http://websecurity.ro/blog/2007/11/02/md5md5-vs-md5/は、それが同等である理由を証明しようとしていますが、その論理はよくわかりません。部分的には、md5(md5(text)) を分析できるソフトウェアがないことを前提としていますが、レインボー テーブルを作成するのは明らかに簡単です。

md5(text) ハッシュよりも md5(md5(text)) タイプのハッシュの数が少ないため、衝突の可能性が高くなり (たとえ可能性が低いとしても)、検索スペースが減少するという私の答えにまだ固執しています。

于 2008-12-07T21:33:12.917 に答える
5

ほとんどの回答は、暗号化やセキュリティのバックグラウンドを持たない人々によるものです。そして、彼らは間違っています。可能であれば、レコードごとに一意のソルトを使用します。MD5/SHA/etc は速すぎます。希望とは逆です。PBKDF2 と bcrypt は遅いですが (これは良いことです)、ASIC/FPGA/GPU で打ち負かすことができます (最近では非常に手頃な価格です)。したがって、メモリハードアルゴリズムが必要です: scrypt を入力してください。

これは、ソルトと速度に関する素人の説明です(ただし、メモリハードアルゴリズムについてではありません)。

于 2012-08-31T13:38:44.237 に答える
4

私はこれを実際的な観点から見ています。後のハッカーは何ですか?なぜ、ハッシュ関数を通過したときに目的のハッシュを生成する文字の組み合わせ。

最後のハッシュのみを保存しているため、ハッカーは1つのハッシュをブルートフォースするだけで済みます。各ブルートフォースステップで目的のハッシュに遭遇する確率がほぼ同じであると仮定すると、ハッシュの数は関係ありません。100万回のハッシュ反復を行うことができますが、セキュリティを1ビット上げたり下げたりすることはありません。これは、行の終わりにブレークするハッシュが1つだけであり、ブレークする確率は他のハッシュと同じだからです。

たぶん、以前の投稿者は、入力が適切であると考えています。そうではありません。ハッシュ関数に入力したものが目的のハッシュを生成する限り、正しい入力または誤った入力を通過します。

さて、レインボーテーブルは別の話です。レインボーテーブルは生のパスワードしか保持しないため、すべてのハッシュのすべてのハッシュを含むレインボーテーブルは大きすぎるため、2回のハッシュは優れたセキュリティ対策になる可能性があります。

もちろん、私はOPが示した例だけを検討しています。ここでは、プレーンテキストのパスワードがハッシュされているだけです。ハッシュにユーザー名またはソルトを含めると、話は別です。レインボーテーブルはすでに大きすぎて実用的ではなく、適切なハッシュが含まれているため、2回のハッシュは完全に不要です。

とにかく、ここではセキュリティの専門家ではありませんが、それは私が私の経験から理解したことです。

于 2011-09-05T07:31:30.647 に答える
3

私が読んだことから、パスワードを数百回または数千回再ハッシュすることが実際に推奨される場合があります。

パスワードのエンコードにもっと時間がかかるようにできれば、攻撃者が多くの推測を実行してパスワードを解読するのはより手間がかかるという考えです。これは、再ハッシュの利点のようです。暗号的に安全であるというわけではありませんが、辞書攻撃の生成に時間がかかるだけです。

もちろん、コンピューターは常に高速になるため、この利点は時間の経過とともに減少します(または反復を増やす必要があります)。

于 2008-12-07T21:46:19.553 に答える
3

一般に、何かを二重ハッシュまたは二重暗号化しても追加のセキュリティは提供されません。ハッシュを一度破ることができれば、もう一度破ることができます。ただし、通常、これを行ってもセキュリティが損なわれることはありません。

MD5 を使用する例では、おそらくご存知のように、いくつかの衝突の問題があります。「二重ハッシュ」は、これに対する保護には実際には役立ちません。同じ衝突でも同じ最初のハッシュが生成され、それを再度 MD5 して 2 番目のハッシュを取得できるからです。

これは、「リバース MD5 データベース」のような辞書攻撃から保護しますが、ソルティングも保護します。

接線では、何かを二重暗号化しても追加のセキュリティは提供されません。これは、実際に使用される 2 つのキーの組み合わせである別のキーが生成されるためです。したがって、実際には 2 つのキーを見つける必要がないため、「キー」を見つける手間が 2 倍になることはありません。通常、ハッシュの結果は元の入力と同じ長さではないため、これはハッシュには当てはまりません。

于 2008-12-07T21:41:42.590 に答える
2

個人的には複数のハッシュを気にすることはありませんが、同じパスワードを持つ2人のユーザーが同じハッシュになってしまわないように、パスワードだけでなくUserName(または別のユーザーIDフィールド)もハッシュするようにします。また、適切な測定のために、おそらく他の定数文字列を入力文字列にスローします。

$hashed_password = md5( "xxx" + "|" + user_name + "|" + plaintext_password);
于 2008-12-07T21:54:01.877 に答える
2

二重ハッシュは、クライアントでパスワードをハッシュし、そのハッシュのハッシュを (異なるソルトで) サーバーに保存する場合にのみ意味があります。

そうすれば、誰かがサーバーにハッキングしたとしても (その結果、SSL が提供する安全性を無視して)、クリアなパスワードを取得することはできません。

はい、彼はシステムに侵入するために必要なデータを持っていますが、そのデータを使用してユーザーが持っている外部のアカウントを侵害することはできません. また、事実上何に対しても同じパスワードを使用することが知られています。

彼がクリアなパスワードにたどり着く唯一の方法は、クライアントに keygen をインストールすることです。それはもはやあなたの問題ではありません。

要するに:

  1. クライアントでの最初のハッシュは、「サーバー違反」シナリオでユーザーを保護します。
  2. サーバー上の 2 番目のハッシュは、誰かがデータベースのバックアップを手に入れた場合にシステムを保護するのに役立つため、それらのパスワードを使用してサービスに接続することはできません。
于 2012-09-04T11:50:01.290 に答える
2

ハッシュ アルゴリズムを使用すると仮定します: rot13 を計算し、最初の 10 文字を取得します。これを 2 回 (または 2000 回) 実行すると、より高速な関数を作成できますが、同じ結果が得られます (つまり、最初の 10 文字を取得するだけです)。

同様に、反復ハッシュ関数と同じ出力を与える、より高速な関数を作成できる可能性があります。したがって、ハッシュ関数の選択は非常に重要です。rot13 の例と同様に、ハッシュを繰り返すことでセキュリティが向上することはありません。アルゴリズムが再帰的な使用のために設計されているという調査結果がない場合は、追加の保護が得られないと想定する方が安全です。

つまり、最も単純なハッシュ関数を除いて、より高速な関数を計算するには暗号化の専門家が必要になる可能性が最も高いため、暗号化の専門家にアクセスできない攻撃者を防御している場合は、実際にはハッシュ関数を繰り返し使用する方がおそらく安全です。 .

于 2011-06-04T13:41:16.313 に答える
0

探索空間の縮小に関する懸念は数学的に正しいですが、探索空間はすべての実用的な目的(ソルトを使用すると仮定)で2^128になるほど十分に大きいままです。ただし、パスワードについて話しているので、封筒裏の計算によると、可能な16文字の文字列(英数字、大文字、いくつかの記号が挿入される)の数は約2^98です。したがって、検索スペースの知覚された減少は実際には関係ありません。

それを除けば、暗号的に言えば、実際には違いはありません。

「ハッシュチェーン」と呼ばれる暗号プリミティブがありますが、これは、システムの整合性を犠牲にすることなく、使用後に署名キーを開示するなど、いくつかのクールなトリックを実行できるようにする手法です。初期の鍵配布の問題をきれいに回避することができます。基本的に、ハッシュのハッシュの大規模なセットを事前計算します--h(h(h(h ....(h(k))...)))、n番目の値を使用して署名し、設定された間隔の後に送信しますキーを取り出し、キー(n-1)を使用して署名します。これで、受信者は以前のすべてのメッセージを送信したことを確認でき、有効な期間が経過したため、誰も署名を偽造できません。

Billが示唆するように、何十万回も再ハッシュすることは、CPUの無駄です。128ビットを壊す人が心配な場合は、より長いキーを使用してください。

于 2008-12-07T21:56:21.903 に答える
0

この記事のいくつかの回答が示唆しているように、セキュリティが向上する場合もあれば、明らかに害を及ぼす場合もあります。セキュリティを確実に向上させるより良いソリューションがあります。ハッシュを計算する回数を 2 倍にする代わりに、salt のサイズを 2 倍にするか、ハッシュで使用されるビット数を 2 倍にするか、またはその両方を行います。SHA-245 の代わりに、SHA-512 にジャンプします。

于 2008-12-08T01:06:09.697 に答える
-1

はい。

のような従来のハッシュ関数の複数回の繰り返しは絶対に使用しないmd5(md5(md5(password)))でください。せいぜい、セキュリティがわずかに向上するだけです (このようなスキームでは、GPU 攻撃に対する保護はほとんど提供されません。パイプラインするだけです)。最悪の場合、追加する反復ごとにハッシュ スペース (したがってセキュリティ) が減少します。 . セキュリティでは、最悪の事態を想定するのが賢明です。

有能な暗号学者によって効果的なパスワード ハッシュとなるように設計されたパスワードを使用し、ブルート フォース攻撃と時空間攻撃の両方に耐性があります。これらには、bcrypt、scrypt、および場合によっては PBKDF2 が含まれます。glibc SHA-256 ベースのハッシュも使用できます。

于 2012-08-31T18:23:53.577 に答える
-1

私は手足を出して、特定の状況ではより安全だと言います...ただし、まだ私に反対票を投じないでください!

数学的/暗号学的な観点からは、他の誰かが私よりも明確な説明を提供すると確信しているため、安全性が低くなります。

ただし、MD5 ハッシュの大規模なデータベースが存在し、MD5 よりも「パスワード」テキストが含まれる可能性が高くなります。したがって、二重ハッシュによって、これらのデータベースの有効性が低下します。

もちろん、塩を使えばこのメリット(デメリット?)はなくなります。

于 2008-12-07T21:38:49.910 に答える
-1

攻撃者がほとんどのハッシュを作成するためにテーブルを作成した可能性が高いため、ダブルハッシュは醜いです。ハッシュをソルトして、ハッシュを混ぜ合わせることをお勧めします。ハッシュに「署名」するための新しいスキーマ (基本的にソルティング) もありますが、より安全な方法です。

于 2008-12-08T00:54:39.767 に答える