18

我知道 PHP 5.5 处于 alpha 阶段,但我正在制作的这个类只是提前制作,以通过使用 function_exists() 来利用它的散列功能。

我查看了password_hash文档。第三个参数是 $options 目前支持两个选项,'salt' 和 'cost'。

它声明如下:

cost,表示应该使用的算法成本。这些值的示例可以在 crypt() 页面上找到。

当我转到 crypt() 页面时,它提供的文档是:

使用盐的河豚散列如下:“$2a$”、“$2x$”或“$2y$”、两位数的成本参数、“$”和字母表中的 22 位数字“./0-9A-Za” -z”。在 salt 中使用超出此范围的字符将导致 crypt() 返回零长度字符串。两位数的成本参数是底层基于 Blowfish 的散列算法的迭代计数的以 2 为底的对数,必须在 04-31 范围内,超出此范围的值将导致 crypt() 失败。5.3.7 之前的 PHP 版本仅支持“$2a$”作为 salt 前缀:PHP 5.3.7 引入了新前缀以修复 Blowfish 实现中的安全漏洞。请参阅 » 本文档以获取有关安全修复的完整详细信息,但总而言之,开发人员仅针对 PHP 5.3。

我似乎无法理解这一点。它说 PHP 5.3.7 和更高版本应该使用 $2y$,但是我用什么成本值来获得那个,它是最好的选择吗?他们提供的示例使用了 7 的值,但根据上述它可以上升到 31,使用say 4 与 say 31 有什么区别?

4

2 回答 2

18

该函数password_hash()只是该函数的一个包装器crypt(),应该使它更容易正确使用。它负责生成安全的随机盐,并提供良好的默认值。

使用此功能的最简单方法是:

$hash = password_hash($password, PASSWORD_DEFAULT);

这意味着,该函数将使用 BCrypt(算法2y)对密码进行哈希处理,生成随机盐,并使用默认成本(目前为 10)。这些都是很好的默认值,特别是我不会生成你自己的盐,在那里很容易出错。

如果您想更改成本参数,您可以这样做:

$hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 11]);

将成本参数增加 1,计算哈希值所需的时间加倍。成本参数是迭代次数的对数(以 2 为底),这意味着:

$iterations = 2 ^ $cost;

编辑:

I missed the point, that you want to generate your own class. For PHP version 5.3.7 and later, there exists a compatibility pack, from the same author that made the password_hash() function. You can either use this code directly, or look at the well crafted implementation. For PHP versions before 5.3.7 there is no support for crypt with 2y, the unicode aware BCrypt algorithm. You can instead use 2a, which is the best alternative for earlier PHP versions. I did an example with a lot of comments, maybe you want to have a look at it too.

P.S. The expressions "salt" and "cost factor" are used correctly in password_hash(), the crypt() function though, uses the word salt for all crypt parameters together, that's a bit misleading.

于 2012-12-17T10:30:55.163 回答
1

免责声明:这是 PHP 5.3.10,但它似乎与您的描述并没有什么不同。

成本适用于计算成本。当您增加成本值时,哈希密码需要更长的时间

function blowfish_salt($cost)
{
    $chars = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt = sprintf('$2y$%02d$', $cost);
    for ($i = 0; $i < 22; ++$i)
        $salt .= $chars[rand(0,63)];

    return $salt;
}

$password = 'My perfect password';
$cost = $argv[1];
$salt = blowfish_salt($cost);
$hash = crypt($password, $salt);

当我在我的(旧)机器上运行它时

php mycrypt.php 10

它立即返回(~0.2 秒),而

php mycrypt.php 16

大约需要 5.2 秒。

于 2012-12-16T22:39:59.077 回答