4

関連する質問:

PHP の crypt() 関数を正しく使用していますか?

SHA-512 または crypt() を使用したパスワード ストレージ ハッシュ (bcrypt)

PHPを使用してパスワードを安全に保存する方法を見つけようとしています。少し読んだ後、hash() の代わりに crypt() を使用する必要があり、bcrypt (bcrypt) または SHA-512 アルゴリズムのいずれかを使用する必要があることを確認しました。 SHA-512 ベースのアルゴリズムもサポートします。

私のソルトはできるだけランダムにすべきであるという多くの提案もありopenssl_random_pseudo_bytes()、コアrand()mt_rand().

私の主な質問は次のとおりです。

  1. bcrypt の使用を選択した場合、どの負荷係数の使用を検討する必要がありますか? PHP 5.5 の場合、新しいパスワード API のデフォルトの負荷係数は 10 であることに気付いたので、少なくともその値が必要になると思います。

  2. 負荷率はパスワードの安全性とどのように関連していますか? 私が理解していることから、アルゴリズムは2^load_factor何度も繰り返されますが、これがブルートフォースクラッキング手法に対する安全性にどのように変換されるかにもっと興味があります. 「安全」とはどういう意味ですか?クラックするのに10年かかるの?5年?1年?

  3. SHA-512 ベースの方法 (またはその逆) よりも bcrypt を選択する必要があるのはなぜですか? SHA-512 は高速ハッシュ方式になるように設計されているため、時間の経過とともに bcrypt ほどうまく機能しないと聞いています。これは本当ですか?どちらの方法にも、crypt を複数回反復できるソルト パラメータがあります。

  4. 私の知る限りでは、bcrypt ソルトを生成する次のテスト コードを実装しました。おすすめの方法は?それを行うより良い方法はありますか?

_

function gen_salt($cost)
{
    return "$2y$" . $cost . "$" . str_replace('+', '.', base64_encode(openssl_random_pseudo_bytes(22)));
}
4

1 に答える 1

1

そのため、コメントに基づいて、さまざまなハッシュ方法にかかる時間をテストするための簡単なベンチマークを作成しました。

function bcrypt_salt($cost)
{
    return "$2y$" . $cost . "$" . str_replace('+', '.', base64_encode(openssl_random_pseudo_bytes(22))) . '$';
}

function sha512_salt($cost)
{
    return "\$6\$rounds=" . $cost . "\$" . openssl_random_pseudo_bytes(16) . '$';
}

$password = "stackoverflow";
$times = 1;
echo "<p>bcrypt method</p>";
for($iters = 10; $iters < 15; ++$iters)
{
    $salt = bcrypt_salt(strval($iters));
    $pword_crypt = crypt($password, $salt);
    $start_time = microtime(true);
    for($i = 0; $i < $times; ++$i)
    {
        crypt($password, $pword_crypt);
    }
    $end_time = microtime(true);
    echo "<p> cost = $iters: " . ($end_time - $start_time) . "</p>";
}

echo "<p>SHA512 method</p>";
for($iters = 1024; $iters < 1000000; $iters *= 2)
{
    $salt = sha512_salt(strval($iters));
    $pword_crypt = crypt($password, $salt);
    $start_time = microtime(true);
    for($i = 0; $i < $times; ++$i)
    {
        crypt($password, $pword_crypt);
    }
    $end_time = microtime(true);
    echo "<p> log2(iters) = ". log($iters,2) . ": " . ($end_time - $start_time) . "</p>";
}

ベンチマーク結果(秒単位の時間):

私のラップトップでi5-m430を使って走った:

bcryptメソッド

コスト=10:0.11740303039551

コスト=11:0.23875308036804

コスト=12:0.46739792823792

コスト=13:0.96053194999695

コスト=14:1.8993430137634

SHA512方式

log2(iters)= 10:0.0034840106964111

log2(iters)= 11:0.0077731609344482

log2(iters)= 12:0.014604806900024

log2(iters)= 13:0.02855396270752

log2(iters)= 14:0.068222999572754

log2(iters)= 15:0.12677311897278

log2(iters)= 16:0.24734497070312

log2(iters)= 17:0.54663610458374

log2(iters)= 18:1.0215079784393

log2(iters)= 19:2.0223300457001

すべてが同じであれば、SHA-512メソッドとbcryptが同じ時間を要するのに比べて、はるかに多くの反復が必要です。そうは言っても、少なくとも10分の1秒かかる方法なら十分だと思います。

于 2012-10-12T20:11:11.667 に答える