【发布时间】:2015-02-19 23:09:01
【问题描述】:
我正在查看this article 并找到了以下格式的哈希,这是我们使用 bcrypt 时返回的。我发现这个哈希应该存储在数据库中(以 varchar(60) 格式左右),并在需要任何用户身份验证时使用。
我的疑问是,如果我的数据库遭到入侵,攻击者将已经知道我使用的算法、成本和盐,这将使他的工作变得非常容易。我是这么认为的,因为现在他甚至不需要猜测他必须使用的算法(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,但它没有说明为什么显示算法(和成本)不是风险,尽管我理解为什么显示盐不是问题。此外,当我尝试更改算法或成本时,这可能会有所帮助的原因似乎不值得冒险。
【问题讨论】:
-
整个东西应该进入数据库。攻击者是否获得盐和算法并不重要。这些不应该是秘密的。此外,如果您没有将盐存储在数据库中,那么您可能对每个密码都使用相同的盐,这是您不应该这样做的。应为每条记录随机生成盐并使用一次。
-
作为一般规则,将安全性留给设计哈希函数的数学家。比我们这些凡人好无限trying to obscure our protocols.
-
@Joel 我确信把安全留给他们是我能做的最好的事情..只是想知道它是如何工作的:-)
-
@meagar 我同意你的观点,这正是我到处读到的。我的问题是“为什么”?