在PHP7 + MySQL中从SHA256哈希密码迁移到BCRYPT

时间:2019-06-16 17:18:54

标签: php mysql passwords bcrypt sha256

我有一个已注册用户的旧Web应用程序,该应用程序使用不安全的hash("sha256", trim($_POST["password"]))将散列密码存储在MySQL数据库中。现在,我想更新Web应用程序以使用更安全的BCRYPT password_hash(),但是我不想给所有注册用户发送电子邮件,提醒他们更改密码。因此,我正在考虑通过以下方式在sha256()哈希密码上实现BCRYPT:

要保存密码,我将对用户密码进行sha256()哈希:

$hashed_password = password_hash(hash("sha256", trim($_POST["password"])), PASSWORD_BCRYPT);

然后,我将BCRYPT哈希密码保存在数据库中。

要验证用户密码,我只需要这样做:

$hashed_password = "select hashed_password from users where email = 'abc@email.com'";

if(password_verify(hash("sha256", trim($_POST["password"])), $hashed_password))
{
    echo "Welcome";
}
else
{
    echo "Wrong Password!";
}

通过这种方式,我将通过循环每个注册用户来更新MYSQL数据库中的用户密码,然后检索sha256()哈希密码,最后我将它与password_hash进行BCRYPT加密后重新保存。 ):

$new_password = password_hash($old_sha256_hashed_password, PASSWORD_BCRYPT);

$mysql->save_user_password($new_password, $user_id);

因此用户仍然可以使用旧密码登录。

您如何看待该解决方案?

即使我在BCRYPT之前将sha256()哈希为密码,它仍然安全吗?

1 个答案:

答案 0 :(得分:1)

由于您当前的哈希系统(未加盐的SHA256)确实非常不安全,因此可以使用双重哈希对密码进行即时保护。尽快,当用户下次登录时,我将切换到新算法并删除双重哈希。

使旧哈希更安全:

$doubleHashToStoreInDb = password_hash($oldUnsaltedSha256HashFromDb, PASSWORD_DEFAULT);

对每一行进行此操作将保护原本不安全存储的密码。请注意PASSWORD_DEFAULT参数,它应优先于特定算法使用,因为它可以用于将来。并标记双哈希,以便您可以区分双哈希和已转换的哈希see why

处理新用户注册:

$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);

只需使用不带双重哈希的新算法即可。

验证登录名:

if (checkIfDoubleHash($storedHash))
{
  $correctPassword = password_verify(oldPasswordHash($_POST["password"]), $storedHash);
  if ($correctPassword)
    storeConvertedHash(password_hash($_POST['password'], PASSWORD_DEFAULT));
}
else
{
  $correctPassword = password_verify($_POST['password'], $storedHash);
}

// Hashes the user password with a deprecated hashing scheme
function oldPasswordHash($password)
{
  return hash("sha256", trim($password));
}

双重哈希将转换为新的密码哈希函数,这是可能的,因为此时我们拥有原始用户密码。新的哈希值通过password_verify()进行了验证,这是一种面向未来且向后兼容的功能。

使密码算法适应将来的硬件不是一项一次性的任务,一旦新硬件变得更快,就必须这样做。 PHP提供了password_needs_rehash()函数来确定是否需要重新哈希,然后您还可以计算并存储新哈希。