我看到一个建议,将回合数设置为($currentYear - 2000)
以说明摩尔定律,以便将2013年设为13
回合,因此2^13
总迭代次数。当然,您需要考虑自己的硬件,以确保它不会花费太长时间(我看到1 second
建议将其作为“安全”来检查密码/哈希,并且在我当前的硬件上,围绕该标记存在13轮回合)。
对于社交网络类型的网站来说,这听起来合理吗?还是将来使用($currentYear - 2000)
将自己设置为非常缓慢的密码检查?
另外,您如何处理将轮数从一年更改为下一年?不会更改轮数来更改哈希,因此不允许您从2014年开始检查2013年的哈希,因为该检查会使用额外的一轮?您是否必须每年重新计算每个哈希,或者它将如何精确地工作?
最佳答案
首先,我对该建议提出质疑(根据年度调整成本)。费用应基于您的硬件速度,而不是当前日期。如果您从现在到2015年之间不升级服务器,则没有理由增加成本。您要做的只是减慢已经很慢的过程。
话虽如此,我也对大多数用法的1秒建议提出质疑。如果您要处理高度敏感的信息,则可以等待1秒(或更长)。但是对于一般的网站,我通常建议在0.25到0.5秒之间。在某些情况下,您可以降低价格,但我会没有充分的理由。
现在,到问题本身。当您使用 crypt()
或 password_hash()
时,迭代计数以返回哈希格式存储。实际上,盐也是如此。因此,计算哈希所需的所有信息都包含在其中!
而且,如果您没有使用任何一种API(或我维护的polyfill:password-compat),那么我真的很想知道为什么您没有使用它们。不要发明自己的密码加密货币。除非您有充分的理由(出于某些政府合规性原因,或者与PHP
通常认为bcrypt是当今最强大的哈希格式。 SCrypt更加强大,但是存在一些问题,它仍然是非常新的(并且在PHP核心中尚不可用)。因此,只需使用bcrypt ...password_hash()
api具有一种机制,可让您执行您要问的事情: password_needs_rehash()
。基本上,您传递哈希值以及今天使用的选项,它会告诉您是否需要重新哈希值:
if (password_verify($password, $hash)) {
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 14])) {
$hash = password_hash($password);
update_password_in_database($hash);
}
$loggedin = true;
}
阅读RFC for password_hash()以获得有关它的更多信息(我从大量来源中收集了数据,并在RFC中包括了引用)。
编辑-跟进@AnotherParker的评论:
正确的。好吧,是的,但是错过了我上面所说的重点。
哈希函数的成本参数是费时的权衡。您需要权衡一些时间,以增加每个哈希的工作量。在相同的硬件上,花费更多的时间将产生更多的工作。产生更多工作的另一种方法是获得更快的硬件。
但是建议是在您当前的硬件上测试哈希函数,并使其尽可能合理地昂贵。如果您今天可以承受的最大时间是0.5秒,那么除非您升级服务器硬件,否则增加的成本将如何为您提供帮助?简而言之,这不会因为您会打破已经确定的重要时间限制而已。
因此,除非不增加散列值,否则就不能在不增加服务器功能的情况下增加工作参数。
另外,请查看this answer on the subject
关于php - 如何持续保持与本年度硬件相关的bcrypt轮次?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15662729/