使用bcrypt时应该在表中存储什么

时间:2014-12-21 19:06:16

标签: php mysql hash bcrypt

我正在浏览this article并找到了以下我们使用bcrypt时返回的哈希格式。我发现这个哈希应该存储在数据库中(以varchar(60)格式左右)并在需要任何用户身份验证时使用。

format of a return value from password_hash()

我怀疑的是,如果我的数据库遭到入侵,攻击者就已经知道算法,成本和我正在使用的盐,这将使他的工作变得非常容易。我是这么认为的,因为现在他甚至不需要猜测他必须用来通过蛮力获取用户密码的算法(bcrypt,SHA,MD5等)。

相反,我觉得我应该只使用最后一部分(最后一个$之后的部分)并在匹配之前在我的脚本中添加其他部分

<?php

$options = array('cost' => 11);
echo password_hash("akki", PASSWORD_BCRYPT, $options)."\n";
// $2y$11$mrblnrK01GWt4g55.Z8Zs.1RslouNzBqCVW826QfBEuaRaVyq96c2

?>

我可以将mrblnrK01GWt4g55.Z8Zs.1RslouNzBqCVW826QfBEuaRaVyq96c2部分存储在数据库中

要针对现有哈希验证用户提供的密码,我可以使用以下函数:

<?php
// Query the db to get $hash.
$hash = 'mrblnrK01GWt4g55.Z8Zs.1RslouNzBqCVW826QfBEuaRaVyq96c2';
$hash = '$2y$11$'.$hash;

if (password_verify('akki', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>

我发现了一个类似的问题here,但它没有说明为什么显示算法(和成本)不是风险,尽管我理解为什么揭示盐不是问题。当我尝试更改算法或成本时,这可能有用的原因似乎并不值得冒险。

1 个答案:

答案 0 :(得分:3)

  

为什么显示算法(和成本)不是风险

因为粗暴强迫它仍然几乎是不可能的。风险没有显着增加。即使知道所使用的算法和成本,每个密码需要很多

通过不存储该信息,您唯一要做的就是更难以升级算法和/或在以后增加成本。这些东西需要升级,因为更强大的硬件,新的攻击方法和更强大的算法等都可以发挥作用。

对于大多数用途来说,实用的是将计算单个散列所需的时间保持在0.3-0.5秒左右。

你做任何使升级和重组变得更加困难的事情都会降低它发生的可能性。这就是引入风险的原因。


当有效的攻击途径与您正在使用的哈希函数相比时,您会怎么做?

这不是理论上的。在GPU加速攻击出现之前,很多人对SHA1非常满意。

如果您要存储整个字符串,那么当用户登录并根据需要重新输入密码时,通过password_needs_rehash()运行它是微不足道的。

如果你已经拆分算法和选项指标并对其进行硬编码 - 你如何升级*?只是更改它们意味着没有旧哈希的人可以登录。并且在用户登录之前你不能生成新的哈希,所以你需要将算法+选项的映射保持到某处的哈希。 ..

像某个数据库。

存储整个字符串。


*如果你没有升级而是通过默默无闻地依赖安全性,那么攻击者只需要确定你使用一次的方法,以便让所有东西都打开。我甚至不打算将此视为一种选择。