最適なbcrypt作業係数


81

パスワードハッシュのための理想的なbcrypt作業要素は何でしょうか。

10の因数を使用する場合、ラップトップでパスワードをハッシュするのに約.1秒かかります。非常に忙しいサイトになってしまった場合、それは人々のパスワードをチェックするだけでかなりの作業になります。

おそらく、作業係数7を使用して、パスワードハッシュ作業の合計をラップトップログインあたり約.01秒に減らす方がよいでしょうか。

ブルートフォースの安全性と運用コストのトレードオフをどのように決定しますか?


7
コストはオフライン攻撃を阻止します。「オンライン」の場合、サービス拒否攻撃を防ぐために、試行間の最小遅延(5秒など)を使用できます。
イアン・ボイド

3
InformationSecurityの複製:bcryptの推奨ラウンド数
Christian Strempfer 2014

1
興味のある人のために、サーバーでbcryptのパフォーマンスをテストするための小さなJava CLIツールを作成しました(これは、セキュリティ、サーバーの負荷、応答時間のバランスを取るために明らかに重要です):github.com/cdraeger/hash-performance
Blacklight

回答:


103

値はパスワードに保存されていることに注意してください$2a$(2 chars work)$(22 chars salt)(31 chars hash)。固定値ではありません。

負荷が高すぎる場合は、次にログインするときに、より高速なものに暗号化して計算できるようにします。同様に、時間が経つにつれてサーバーが改善され、負荷が問題にならない場合は、ログイン時にハッシュの強度をアップグレードできます。

秘訣は、ムーアの法則に従って、将来にわたってほぼ同じ時間を永遠に費やし続けることです。数値はlog2であるため、コンピューターの速度が2倍になるたびに、デフォルトの数値に1を加算します。

ユーザーのパスワードをブルートフォースするのにかかる時間を決定します。たとえば、一般的な辞書の単語の場合、アカウントの作成により、パスワードが弱いことをすでに警告されている可能性があります。たとえば、それが1000の一般的な単語の1つであり、攻撃者がそれぞれをテストするのに0.1秒かかる場合、100を購入します(まあ、いくつかの単語はより一般的です...)。ユーザーが「一般的な辞書の単語」+2つの数字を選択した場合、それは2時間以上になります。パスワードデータベースが侵害され、攻撃者が1日に数百のパスワードしか取得できない場合、パスワードを安全に変更するために、ほとんどのユーザーを数時間または数日購入しています。それは彼らに時間を買うことの問題です。

http://www.postgresql.org/docs/8.3/static/pgcrypto.htmlには、パスワードを解読するための考慮事項がいくつかあります。もちろん、彼らがリストしているパスワードはランダムな文字です。辞書の単語...実際には、パスワードが12345の人を救うことはできません。


8
これは本当に素晴らしい答えです。ログインのアイデアを再暗号化することすら考えていませんでした。どうもありがとうございます!
クリス

1
暗号化はどのように機能しますか?古いbcryptの作業コストをどこかに保存してログインできるようにし、パスワードを検証した後、データベースのハッシュとコストを更新する必要がありますか?
ジェリーサラビア2013年

6
@JerrySaravia bcryptの利点は、コストがハッシュ自体に格納されることです。したがって、余分なものを格納する必要はありません。現在のハッシュで認証するだけで、すぐに別のコストでハッシュを再生成できます。シンプル!
マークロッカー2013

@ MarkLocker、ありがとうマーク!それは美しい[美しい]地下室です!しかし、真剣に、それは物事をはるかに簡単にし、素晴らしいことです。
ジェリーサラビア2013

「返信の試みが間違っている」ために編集することは許可されていないので(私の編集内容を読んでもらえますか?)、代わりに情報にコメントさせてください。値の例:$2y$08$fJS4yx0i8kiOzIBIamZ51OWTMrzyE/4je34Oxhw.5xxp3Es7Ke32W。編集しようとした理由:「2文字で動作する」が数字なのか16進数なのか、テストする必要があるのか​​どうかはわかりませんでした。これが他のみんなのテスト結果ですので、自分で試してみる必要はありません。
Luc

3

短縮版

計算に少なくとも250ミリ秒を与える反復回数

ロングバージョン

BCryptが最初に公開されたとき、1999年に、彼らは実装のデフォルトのコスト要因をリストしました。

  • 通常のユーザー:6
  • スーパーユーザー:8

6のbcryptコストは64ラウンドを意味します(2 6 = 64)。

彼らはまた注意します:

もちろん、人々が選択するコストは、時々再評価する必要があります

  • 1976年の展開時点では、cryptは1秒あたり4つ未満のパスワードをハッシュできました。(パスワードあたり250ミリ秒)
  • 1977年、VAX-11 / 780では、crypt(MD5)を1秒間に約3.6回評価できました。(パスワードあたり277ミリ秒)

これにより、元の実装者が作成時に検討していた種類の遅延のフレーバーが得られます。

  • 通常のユーザーの場合は約250ミリ秒
  • スーパーユーザーの場合は最大1秒。

しかし、もちろん、長く立つことができるほど良いです。私が見たすべてのBCrypt実装は10、デフォルトのコストとして使用されました。そして私の実装はそれを使用しました。デフォルトのコストを12に増やす時が来たと思います。

ハッシュごとに250ミリ秒以上をターゲットにすることにしました。

私のデスクトップPCは、Intel Core i7-2700K CPU @ 3.50GHzです。私は当初、2014年1月23日にBCrypt実装のベンチマークを行いました。

1/23/2014  Intel Core i7-2700K CPU @ 3.50 GHz

| Cost | Iterations        |    Duration |
|------|-------------------|-------------|
|  8   |    256 iterations |     38.2 ms | <-- minimum allowed by BCrypt
|  9   |    512 iterations |     74.8 ms |
| 10   |  1,024 iterations |    152.4 ms | <-- current default (BCRYPT_COST=10)
| 11   |  2,048 iterations |    296.6 ms |
| 12   |  4,096 iterations |    594.3 ms |
| 13   |  8,192 iterations |  1,169.5 ms |
| 14   | 16,384 iterations |  2,338.8 ms |
| 15   | 32,768 iterations |  4,656.0 ms |
| 16   | 65,536 iterations |  9,302.2 ms |

ここに画像の説明を入力してください

将来の保証

定数を固定するのではなく、最小値を固定する必要があります

パスワードハッシュ関数を使用するのではなく、次のようにします。

String HashPassword(String password)
{
   return BCrypt.HashPassword(password, BCRYPT_DEFAULT_COST);
}

次のようになります。

String HashPassword(String password)
{  
   /*
     Rather than using a fixed default cost, run a micro-benchmark
     to figure out how fast the CPU is.
     Use that to make sure that it takes **at least** 250ms to calculate
     the hash
   */
   Int32 costFactor = this.CalculateIdealCost();
   //Never use a cost lower than the default hard-coded cost
   if (costFactor < BCRYPT_DEFAULT_COST) 
      costFactor = BCRYPT_DEFAULT_COST;

   return BCrypt.HashPassword(password, costFactor);
}

Int32 CalculateIdealCost()
{
    //Benchmark using a cost of 5 (the second-lowest allowed)
    Int32 cost = 5;

    var sw = new Stopwatch();
    sw.Start();
    this.HashPassword("microbenchmark", cost);
    sw.Stop();

    Double durationMS = sw.Elapsed.TotalMilliseconds;

    //Increasing cost by 1 would double the run time.
    //Keep increasing cost until the estimated duration is over 250 ms
    while (durationMS < 250)
    {
       cost += 1;
       durationMS *= 2;
    }

    return cost;
}

そして理想的には、これはすべてのBCryptライブラリの一部であるため、ライブラリのユーザーに定期的にコストを増やすのではなく、コスト自体が定期的に増加します。

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