何が理想的なパスワードハッシングアルゴリズムのようになりますか?

免責事項:SOには多くの同様の質問がありますが、私は単なる一般原則ではなく、実用的な提案を探しています。また、 "理想的な"アルゴリズムの実装を指摘することも自由ですが(PHPはうまくいくでしょう)、具体的な方法(動作方法)を記述してください。

データベースに格納するためのパスワードのハッシュ文字列を計算する最良の方法は何ですか?私は私がすべきことを知っている

  • 塩を使用する
  • ハッシュ処理を複数回繰り返します(キーストレッチのハッシュチェーン)

私はそのようなアルゴリズムを使用することを考えていた:

x = md5( salt + password);
repeat N-times:
    x = md5( salt + password + x );

私はこれがかなり安全だと確信していますが、心に来るいくつかの質問があります:

  1. ユーザー名を塩に入れることは有益でしょうか?

  2. 私はすべてのユーザーに共通の塩を使用することを決めましたが、これには何らかの欠点がありますか?

  3. もしあれば、推奨される最小塩分は何ですか?

  4. md5、shaなどを使用する必要がありますか?

  5. 上記のアルゴリズムや提案に何か問題がありますか?

  6. ...(気軽にもっと:)

私は決定が必然的に状況に依存していることを知っていますが、私は解決策を探しています:

  • provide as much security as possible
  • be fast enough ( < 0.5 second on a decent machine )

だから、理想的なアルゴリズムは、擬似コードでどのように見えるでしょうか?

2
キーストレッチについては、それを反映するように質問を更新しました。
追加された 著者 johndodo,
なぜ繰り返しハッシングですか?
追加された 著者 GazTheDestroyer,

2 答え

現在の "理想的な"パスワードハッシュ関数は、 bcrypt です。これには塩分処理と構成可能な繰り返し回数が含まれています。 無料のオープンソースPHPの実装があります。

2番目に良いのは PBKDF2 です。これは基本的なハッシュ関数に依存していますが、提案する。 技術的な理由があります。 bcryptがPBKDF2よりも「良い」理由


あなたの特定の質問については:

1。ユーザー名を塩に入れるのは有益でしょうか?

あんまり。

2。私はすべてのユーザーに共通の塩を使用することを決めましたが、これには何らかの欠点がありますか?

はい:それは塩を飲むことの利点を取り除きます。存在するsalt単独の理由は、各ハッシュされたパスワードに対して一意であることです。これにより、攻撃者が2つのハッシュされたパスワードを攻撃するのを防ぐことができます。塩はユニークでなければなりません。ユーザーごとの塩を持っていても、悪いです:ユーザーがパスワードを変更したときに塩を変更する必要があります。 saltが再利用/共有されるときに攻撃者が適用できる最適化の種類には、虹の表を参照してください。

3。もしあれば、推奨される最小塩の長さは何ですか?

塩は一意でなければなりません。一意性は維持するのが難しい性質です。しかし、(十分な乱数生成器、好ましくは暗号的に強い乱数生成器で生成された)長すぎるランダムな塩を使用することによって、十分に高い確率で一意性が得られます。 128ビットの塩は十分に長いです。

4。 md5、shaなどを使用する必要がありますか?

MD5は広報には悪い。特定の用途に適用される場合と適用されない場合がある既知の弱点があり、これらの弱点が特定の状況に当てはまらないような信頼性をもって「証明する」ことは非常に困難です。 SHA-1はMD5よりもはるかに深刻ではないにもかかわらず、弱点を持っているので、SHA-1は良いですが「良い」ではありません。 SHA-256は合理的な選択です。上で指摘したように、パスワードハッシュのために、 rel = "nofollow noreferrer"> GPU 、そしてSHA-256のスケールがうまくいきます。そのため、bcryptで使用されるBlowfishの派生が望ましいのです。

5。上記のアルゴリズム/提案に間違いがありますか?

手作りです。それは良くないね。問題は、暗号化アルゴリズムのセキュリティに関する既知のテストがないことです。私たちが望むことができる最高のものは、数百人のプロの暗号技術者が数年間アルゴリズムを壊そうとすることです。もしそうでないなら、アルゴリズムは実際に安全であることが証明されていませんが、明らかであってはならない。 Bcryptは12年にわたって、広く普及し、分析されてきました。 StackOverflowの助けを借りても、あなた自身でそれを打つことはできません。

私は専門の暗号化技術者として、MD5またはSHA-256の単純連結を使用して疑わしい眉を立てます。これらは Merkle-Damgårdハッシュ関数。衝突耐性はありますが、ランダムなオラクル(いわゆる「長さ拡張攻撃」)があります。 。 PBKDF2では、ハッシュ関数は直接使用されるのではなく、 HMAC を介して使用されます。

6
追加された
ありがとう、それはまさに私が望んでいたものです - 私はbcryptを知らなかったことを認めなければなりません。今私はそれについての情報をネットで検索しました。私は理由を知っています...これは最高の秘密の一つでなければなりません...;)私はあなたの投稿に同意します。質問。どのように適切にbcryptを使用するかに関する提案? phpass または その他 クラス
追加された 著者 johndodo,
この回答はphpassを推奨していますそれを使用する方法の詳細。私は自分でPHPで開発することはありません。
追加された 著者 Thomas Pornin,

私は固定されたアプリケーションの塩、ユーザー名とパスワードを使用する傾向があります

例...

string prehash = "mysaltvalue" + "myusername" + "mypassword";

ここでの利点は、同じパスワードを使用する人が同じハッシュ値にならず、データベースにアクセスできるユーザーが別のユーザーにパスワードをコピーすることを防ぐことです。もちろん、DBにアクセスできない場合本当にデータを取得するためにログインをハッキングする必要があります;)

IMO、塩分の長さはそれほど重要ではありませんが、ハッシュ値の長さは常に32になります(MD5を使用します - これもまた私が使用するものです)

私はセキュリティの面で言えば、このパスワードの暗号化で十分ですが、最も重要なことは、あなたのアプリケーション/データベースにセキュリティリークがないことを確認することです!

また、繰り返しハッシュをしても気にしませんでしたが、私の意見ではありません。誰かがそれをハックしようとするアルゴリズムを知っていなければならないでしょうし、それが何回もハッシュされていればそれは重要ではありません。

1
追加された
複数回のハッシュ処理で必要な計算量が増えます。 1回限りの認証では安いですが、攻撃者にとって急速に高価になります。
追加された 著者 Roger Lipscombe,
まったく。 :) @musefan:私は "良い"の代わりに "ベストプラクティス"のソリューションを探しています。物事を正しく行うことには何のダメージもありません。そこにはセキュリティソリューションがあまりにも多すぎます(あなたのものはその1つではありません)。ソルトキーの長さは、ハッシュされた文字列を長くするために重要です - 大きなレインボーテーブルが必要です(私は思う)。私は他の穴についても同意しますが、それは全く新しいテーマです。 :)
追加された 著者 johndodo,
@RogerLipscombe:はい、良い点。
追加された 著者 musefan,
@ジョンドド:塩の鍵を知っていれば長さは重要ではない、もし彼らが虹のテーブルを使っているならば、ハッシュを直接ハッキングしたり、ログイン機能を使う可能性がある(その場合、彼らは塩を気にする必要はない)
追加された 著者 musefan,