将md5密码哈希转换为PHP 5.5 password_hash()

Aro*_*ron 9 php security passwords hash php-password-hash

PHP 5.5中新的password_hash API很不错,我想开始在任何地方使用它.鉴于较旧的项目具有较旧的数据库,其中密码存储在md5哈希中,将旧用户密码迁移到新的更安全的API的最佳方法是什么?

除了简单地提示用户在下次登录时重置密码(这对用户来说这是不切实际和烦人的)我还考虑过使用当前md5哈希作为所有现有用户的password_hash()输入的可能性.为了验证这些用户的密码(在登录期间),我将他们的输入转换为md5哈希,然后将其用于password_verify().新用户将免于这一额外的步骤.

这是一个值得这样做的方法吗?是否有更好的透明迁移方式,用户不会因密码重置而烦恼,但我可以立即享受更安全的哈希带来的好处吗?

最重要的是,在使用现有的md5哈希(易于暴力)和使用password_hash()API来"双重哈希"时,是否还有安全优势?

小智 12

在你的login.php(?)中,将旧密码从MD5转换为bcrypt,并用新的密码替换数据库中的旧MD5哈希.

伪代码:

$password = $_POST["password"];

if (substr($pwInDatabase, 0, 1) == "$")
{
    // Password already converted, verify using password_verify
}
else
{
    // User still using the old MD5, update it!

    if (md5($password) == $pwInDatabase)
    {
        $db->storePw(password_hash($password));
    }
}
Run Code Online (Sandbox Code Playgroud)

双散列不会增加bcrypt的安全性,因为bcrypt itsef是一种单向散列函数.

注意:MD5产生一个32个字符长度的字符串,而password_hash()最小值为60.

阅读手册:

如果您决定使用password_hash()或兼容包(如果PHP <5.5)https://github.com/ircmaxell/password_compat/,请务必注意,如果您当前的密码列的长度低于60,则将需要更改为(或更高).手册建议长度为255.

您需要更改列的长度并重新开始使用新哈希才能使其生效.否则,MySQL将无声地失败.