doujia6503 2012-10-12 09:40
浏览 36
已采纳

密码和密码存储问题

Related questions:

Am I using PHP's crypt() function correctly?

Password storage hash with SHA-512 or crypt() with blowfish (bcrypt)

I'm trying to figure out how I should safely store a password using PHP. After a little reading I've identified that I should use crypt() instead of hash() and that I should use either the blowfish (bcrypt) or SHA-512 algorithms, with I believe bcrypt being recommended more often, though there is significant support for SHA-512 based algorithms, too.

There are also many suggestions that my salt should be as random as possible, with many suggestions to use openssl_random_pseudo_bytes() over the core rand() and mt_rand().

My main questions are:

  1. If I choose to use bcrypt, what load factors should I consider using? I noticed that for PHP 5.5 the default load factor in the new password API is 10 so I would imagine I would want at least that value.

  2. How does the load factor correlate to password safety? From what I understand the algorithm will iterate 2^load_factor times, but I'm more interested in how this translates into safety against brute force cracking methods. What does it mean to be "safe"? Does it take 10 years to crack? 5 years? 1 year?

  3. Why should I pick bcrypt over a SHA-512 based method (or vise-versa)? I've heard that SHA-512 is designed to be a fast hashing method so over time it won't hold up as well as bcrypt. Is this true? Both methods have salt parameters which allow crypt to iterate multiple times.

  4. To the best of my knowledge, I implemented the following test code which generates a bcrypt salt. Is the recommended method? Is there a better way to do it?

_

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

1条回答 默认 最新

  • duanreng3439 2012-10-12 20:11
    关注

    So based off of the comments I created a simple benchmark to test how long various hashing methods take.

    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>";
    }
    

    Benchmark results (time in seconds):

    Ran on my laptop with an i5-m430:

    bcrypt method

    cost = 10: 0.11740303039551

    cost = 11: 0.23875308036804

    cost = 12: 0.46739792823792

    cost = 13: 0.96053194999695

    cost = 14: 1.8993430137634

    SHA512 method

    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

    All things being equal, it takes a much higher number of iterations for the SHA-512 method vs. bcrypt to take the same amount of time. That being said I'm guessing that any method which takes at least a tenth of a second is more than sufficient.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 怎么在stm32门禁成品上增加记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面
  • ¥50 NT4.0系统 STOP:0X0000007B
  • ¥15 想问一下stata17中这段代码哪里有问题呀
  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 解riccati方程组