3

有没有办法将MD5密码转换为可以验证的东西password_verify()

我在Crypt Wikipedia 页面上读到“密码哈希的可打印形式以.MD5开头”。$1$

因此,我试一试(没有任何运气):

$password = "abcd1234";
$md5hash = "$1$".md5($password);
var_dump(password_verify($password, $md5hash));

有没有办法password_verify()使用MD5密码?

问题原因:我有一个旧系统,其中密码存储为MD5哈希值。我想开始使用更安全的Password Hashing API. 如果我能够将现有的密码散列转换为可以使用的东西password_verify(),我可以只更新数据库条目($1$添加到所有密码散列之前),我的程序将使用以下代码很好地工作(我不必制作旧MD5密码的特殊情况):

$password; // Provided by user when trying to log in
$hash; // Loaded from database based on username provided by user
if(password_verify($password, $hash)) {
   // The following lines will both update the MD5 passwords
   // and all passwords whenever the default hashing algorithm is updated
   if(password_needs_rehash($hash, PASSWORD_DEFAULT)) {
      $hash = password_hash($password, PASSWORD_DEFAULT);
      // Store the new hash in database
   }
   // User is logged in
} else {
   // User is not logged in
}
4

2 回答 2

6

你不能那样做。

您可以做的是对已经经过 MD5 哈希处理的密码进行哈希处理,password_hash()并在数据库中为这些旧密码添加一个附加标志,这样您就知道以后要对它们进行双重验证。

一些示例代码:

$passwordCompare = ($passwordIsOldFlag === true)
    ? md5($密码输入)
    :$密码输入;

if (password_verify($passwordCompare, $passwordHash))
{
    if ($passwordisOldFlag === true)
    {
        $passwordNewHash = password_hash($passwordInput, PASSWORD_DEFAULT);

        // 在这里,您将使用新的纯 bcrypt 哈希更新数据库
        // 并将您的 passwordIsOldFlag 也设置为 0
    }
}

注意:MD5 产生一个 32 个字符长度的字符串,而password_hash()最少是 60 个。

阅读手册:

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

您需要更改列的长度并使用新的哈希重新开始以使其生效。否则,MySQL 将静默失败。

于 2015-07-30T11:35:22.267 回答
0

md5(或任何其他散列算法 - 查看完整列表hash_algos())每次都会将某些东西散列到一个常量(相同)的东西,换句话说:

'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
'1234' ---md5---> '81dc9bdb52d04dc20036dbd8313ed055'
...

password_hash($password, $algo)每次都会将一些东西散列成一个新东西,换句话说:

'1234' ---password_hash---> '$2y$10$VXj5/N79aVolZQHJa.wdUub4C1uifXCNGRVKVUIYnsuRGs/wnXU/S'
'1234' ---password_hash---> '$2y$10$BjSPyCyZU2Rui5MtL5MLC.bkLGbUxf/f9NshALvTc39lhemoWZFC6'
'1234' ---password_hash---> '$2y$10$WXGX/6dCLbJN77MKNNVbCej9Fya2fQGvPjAMLuU3a6zGCDuBMisbm'
'1234' ---password_hash---> '$2y$10$sqkB2ZK7BanIHTRZIKUHi.TVdseZE.GSMghBhuT7mDC9GrjW9g6Ky'

所以 hash_verify_kind_function() 只需要用于制作的哈希,password_hash()因为您可以使用 md5 (或任何)对您的字符串进行哈希处理,然后检查它们是否相等,这是非常愚蠢的工作,因为在这种情况下您不需要先用md5散列!因为实际上 md5 散列不用于密码散列(因此验证)

于 2020-10-12T05:30:02.717 回答