在 PHP7+MySQL 中从 SHA256 哈希密码迁移到 BCRYPT
Migrate from SHA256 hashed passwords to BCRYPT in PHP7+MySQL
我有一个旧的 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():
加密
$new_password = password_hash($old_sha256_hashed_password, PASSWORD_BCRYPT);
$mysql->save_user_password($new_password, $user_id);
因此用户仍然可以使用旧密码登录。
您如何看待这个解决方案?
即使我在 BCRYPT 之前对密码进行 sha256() 哈希,它仍然安全吗?
由于您当前的哈希系统(未加盐的 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() 验证,这是一个未来证明和向后兼容的函数。
使密码算法适应未来的硬件不是 one-time 任务,一旦新硬件变得更快,就有必要这样做。 PHP提供函数password_needs_rehash()判断是否需要重新哈希,然后你也可以计算一个新的哈希并存储它。
我有一个旧的 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():
加密$new_password = password_hash($old_sha256_hashed_password, PASSWORD_BCRYPT);
$mysql->save_user_password($new_password, $user_id);
因此用户仍然可以使用旧密码登录。
您如何看待这个解决方案?
即使我在 BCRYPT 之前对密码进行 sha256() 哈希,它仍然安全吗?
由于您当前的哈希系统(未加盐的 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() 验证,这是一个未来证明和向后兼容的函数。
使密码算法适应未来的硬件不是 one-time 任务,一旦新硬件变得更快,就有必要这样做。 PHP提供函数password_needs_rehash()判断是否需要重新哈希,然后你也可以计算一个新的哈希并存储它。