在PHP 5.5中生成密码哈希并设置成本选项

时间:2012-12-16 21:57:33

标签: php passwords bcrypt php-password-hash

我知道PHP 5.5是alpha版本,但我正在制作的这个类是通过使用function_exists()来提前使用它的散列函数。

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

它陈述如下:

  

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

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

  

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

我似乎无法理解这个问题。它说PHP 5.3.7及更高版本应该使用$ 2y $,但是我用什么成本来获得那个并且它是最好的选择值?他们提供的示例使用的值为7,但根据上述情况,它可以达到31,使用说4而不是说31会有什么不同?

2 个答案:

答案 0 :(得分:16)

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

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

$hash = password_hash($password, PASSWORD_DEFAULT);

这意味着,该函数将使用BCrypt(算法2y)散列密码,生成随机盐,并使用默认成本(此时为10)。这些是很好的默认值,特别是我生成你自己的盐,很容易在那里犯错误。

如果您想更改费用参数,可以这样做:

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

将cost参数增加1,将计算哈希值所需的时间加倍。 cost参数是迭代计数的对数(base-2),表示:

$iterations = 2 ^ $cost;

编辑:

我错过了这一点,你想要自己创建一个类。对于PHP 5.3.7及更高版本,存在compatibility pack,来自同一作者的password_hash()函数。您可以直接使用此代码,也可以查看精心设计的实现。对于5.3.7之前的PHP版本,不支持具有crypt的{​​{1}},即具有unicode感知的BCrypt算法。您可以使用2y,这是早期PHP版本的最佳替代方案。我做了很多评论的example,也许你也想看看它。

P.S。表达式“salt”和“cost factor”在2a中正确使用,crypt()函数虽然对所有crypt参数使用了单词salt,但这有点误导。

答案 1 :(得分: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秒。