从SHA256哈希密码迁移到PHP7+;MySQL

从SHA256哈希密码迁移到PHP7+;MySQL,php,mysql,passwords,bcrypt,sha256,Php,Mysql,Passwords,Bcrypt,Sha256,我有一个注册了几个用户的旧web应用程序,它使用不安全的散列(“sha256”,trim($\u POST[“password”])将散列密码存储在MySQL数据库中。现在我想更新web应用程序以使用更安全的BCRYPTpassword\u hash(),但是我不想通过电子邮件通知所有注册用户更改密码。因此,我考虑在sha256()哈希密码上实现BCRYPT,方法如下: 要保存密码,我将sha256()散列用户密码: $hashed_password = password_hash(hash("

我有一个注册了几个用户的旧web应用程序,它使用不安全的
散列(“sha256”,trim($\u POST[“password”])
将散列密码存储在MySQL数据库中。现在我想更新web应用程序以使用更安全的BCRYPT
password\u 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()散列密码,最后在使用密码\u hash()对其进行BCRYPTed后重新保存:

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

你觉得这个解决方案怎么样


即使我先对密码进行sha256()散列,然后再对其进行BCRYPT,它仍然安全吗?

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

使旧哈希更安全: 对每行执行此操作将保护以其他方式不安全存储的密码。注意
PASSWORD\u DEFAULT
参数,它应该优先于特定算法,因为它是未来的证明。并标记双哈希,以便区分双哈希和已转换的哈希

处理新用户注册: 只需使用新算法,无需双重哈希

验证登录: 双哈希将转换为新的密码哈希函数,这是可能的,因为我们现在有原始用户密码。新的哈希值经过验证,它是一个面向未来且向后兼容的函数


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

如果您没有用户密码,则无法重新哈希。只有当用户登录时,您才知道密码,然后您可以重新设置它。@Dharman我知道这一点,这就是为什么我在BCRYPT之前先对用户的密码进行sha256()散列,这样经过sha256()散列的旧保存密码将对旧用户有效。我现在已经测试过了,一切都很好,旧的sha256()哈希密码一旦转换成BCRYPT,就可以正常工作了。我只需要知道它是否仍然安全,因为在BCRYPT之前我先对用户的密码进行了sha256()散列。让我重新表述一下:将用户的密码完全重新散列到一个新系统中是个好主意。每次用户使用旧方法登录时,都会重新刷新其密码。我认为没有必要无限期地保留这种双重制度,但暂时保留可能是个好主意。如果你不想强迫用户更改密码,你至少可以在下次登录时为他们重新设置密码。啊,我现在得到了,谢谢,是的,这是一个很好的建议,我会实施它。
$new_password = password_hash($old_sha256_hashed_password, PASSWORD_BCRYPT);

$mysql->save_user_password($new_password, $user_id);
$doubleHashToStoreInDb = password_hash($oldUnsaltedSha256HashFromDb, PASSWORD_DEFAULT);
$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));
}