从技术上讲,第二次调用 ofpassword_hash
是不必要的。然而,它非常有用,不应该被忽略!正如 Mark 已经提到的,第二次调用有助于使您存储的哈希值保持最新。
但是您的代码片段中有一个非常重要的缺陷。您从文档中复制的部分很好,但您扩展它的方式不正确。那么发生了什么?第一次调用从明文密码password_hash
创建一个散列。然后使用参数,调用。这是有问题的部分。此调用将始终产生,因为您正在验证明文密码是否与刚刚创建的自身哈希匹配。这永远不会失败,最终使条件变得无用。password_verify
$plaintextPassword
$hashedPassword
TRUE
错误是您第一次调用password_hash
. 在这一点上,你不会散列$plaintextPassword
. 相反,您应该从数据库中检索该用户已存储的密码哈希。接下来,您将以这样password_verify
的方式调用:password_verify($plaintextPassword, $hashedPasswordFromDatabase))
. 这确保输入的明文密码与您已经知道的密码哈希相匹配。
// drop that line
//$hashedPassword = password_hash($plaintextPassword, PASSWORD_DEFAULT, $options);
// and replace it with something like this
$hashedPasswordFromDatabase = $db->getPasswordHashForUserId(42);
// match the plaintext pw an the pw from db
if (password_verify($plaintextPassword, $hashedPasswordFromDatabase))
{
...
然后password_needs_rehash
检查该密码哈希(取自数据库)是否仍然是最新的。如果它发现哈希已被弃用,则条件成立并password_hash
再次调用。要了解这为何有用,请想象以下情况:您在接下来的几天发布您的网站。用户创建帐户,当前活动的散列算法CRYPT_BLOWFISH用于创建用户的散列。你的网站变得如此成功,它在 2020 年仍然活跃。到那时(很可能更早)更好的散列算法成为默认值。然后将使用更好的算法自动创建新用户的密码,因为您使用的是常量PASSWORD_DEFAULT
这将在另一个 PHP 版本中返回该其他散列算法。对于新用户来说,这很好。但是,如果您的代码中没有第二次调用,则已经存在的用户密码不会被重新散列并且实际上不会被更新password_hash
。
长话短说:在您的代码片段中进行第二次调用,以使您的代码更加面向未来。
要解决您的其他问题:
的成本12
现在可能没问题,但这是您应该不时调整的值。取自文档:
建议您在服务器上测试此功能,并调整成本参数,使该功能在交互式系统上的执行时间少于 100 毫秒。
因此,您应该增加它以在您的服务器硬件上产生所需的延迟。但也要注意,增加太多可能会使您容易受到拒绝服务攻击。
有关密码哈希的详细介绍,请查看crackstation 上的这篇精彩文章:https ://crackstation.net/hashing-security.htm