doutan1875 2015-07-30 10:30
浏览 275
已采纳

使用password_verify()验证MD5密码

Is there a way to convert a MD5 password to something that can be verified by password_verify()?

I read on the Crypt Wikipedia page that "The printable form of MD5 password hashes starts with $1$."

Hence I give this a shot (without any luck):

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

Is there any way to make password_verify() work with MD5 passwords?

Reason for question: I have an old system where the passwords are stored as MD5 hashes. I want to start using the more secure Password Hashing API. If I'm able to convert the existing password hashes to something that works with password_verify(), I can just update the database entries (prepend $1$ to all password hashes), and my program would work beautifully using the following code (I don't have to make a special case for the old MD5 passwords):

$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
}
  • 写回答

1条回答 默认 最新

  • dsgawmla208057 2015-07-30 11:35
    关注

    You can't do that.

    What you can do is to hash the already MD5-hashed passwords via password_hash() and put an additional flag for these old passwords in your database, so you know to double-verify them afterwards.

    Some sample code:

    $passwordCompare = ($passwordIsOldFlag === true)
        ? md5($passwordInput)
        : $passwordInput;
    
    if (password_verify($passwordCompare, $passwordHash))
    {
        if ($passwordisOldFlag === true)
        {
            $passwordNewHash = password_hash($passwordInput, PASSWORD_DEFAULT);
    
            // Here, you'd update the database with the new, purely bcrypt hash
            // and set your passwordIsOldFlag to 0 as well
        }
    }
    

    Note: MD5 produces a 32 character length string, while password_hash() is a minimum of 60.

    Read the manual:

    If and when you do decide to use password_hash() or the compatibility pack (if PHP < 5.5) https://github.com/ircmaxell/password_compat/, it is important to note that if your present password column's length is anything lower than 60, it will need to be changed to that (or higher). The manual suggests a length of 255.

    You will need to ALTER your column's length and start over with a new hash in order for it to take effect. Otherwise, MySQL will fail silently.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能