You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

password_hash加密后password_verify验证失败,求问题排查

password_verify()验证密码失败问题排查

注册时设置密码为“1”,使用password_verify()验证数据库中存储的哈希密码时无法通过,但使用md5()或sha1()哈希时验证正常。已知password_hash是更安全的密码哈希实现,需找出问题所在。

相关代码

handleForms.php

if (isset($_POST['registerUserBtn'])) {

    $username = sanitizeInput($_POST['username']);
    $first_name = sanitizeInput($_POST['first_name']);
    $last_name = sanitizeInput($_POST['last_name']);
    $password = $_POST['password'];
    $confirm_password = $_POST['confirm_password'];

    if (!empty($username) && !empty($first_name) && !empty($last_name) && !empty($password) && !empty($confirm_password)) {

        if ($password == $confirm_password) {

            $insertQuery = insertNewUser($pdo, $username, $first_name, 
                $last_name, password_hash($_POST['password'], PASSWORD_DEFAULT));

            if ($insertQuery) {
                header("Location: ../login.php");
            }
            else {
                header("Location: ../register.php");
            }

        }

        else {
            $_SESSION['message'] = "请确保两次输入的密码一致";
            header("Location: ../register.php");
        }
    }

    else {
        $_SESSION['message'] = "请确保所有输入字段不为空!";
        header("Location: ../register.php");
    }
}

if (isset($_POST['loginUserBtn'])) {

    $username = sanitizeInput($_POST['username']);
    $password = $_POST['password'];

    if (!empty($username) && !empty($password)) {

        $loginQuery = loginUser($pdo, $username, $password);
        $userIDFromDB = $loginQuery['user_id']; 
        $usernameFromDB = $loginQuery['username']; 
        $passwordFromDB = $loginQuery['password'];

        echo "你输入的密码: " . $password . "<br>";
        echo "数据库存储的哈希: " . $passwordFromDB . "<br>";

        if (password_verify($password, $passwordFromDB)) {
            echo "验证通过";
        }

        else {
            echo "验证失败";
        }
    }

    else {
        $_SESSION['message'] = "请确保登录输入字段不为空!";
        header("Location: ../login.php");
    }
 
}

models.php

function insertNewUser($pdo, $username, $first_name, $last_name, $password) {

    $checkUserSql = "SELECT * FROM user_accounts WHERE username = ?";
    $checkUserSqlStmt = $pdo->prepare($checkUserSql);
    $checkUserSqlStmt->execute([$username]);

    if ($checkUserSqlStmt->rowCount() == 0) {

        $sql = "INSERT INTO user_accounts (username, first_name, last_name, password) VALUES(?,?,?,?)";
        $stmt = $pdo->prepare($sql);
        $executeQuery = $stmt->execute([$username, $first_name, $last_name, $password]);

        if ($executeQuery) {
            $_SESSION['message'] = "用户注册成功";
            return true;
        }

        else {
            $_SESSION['message'] = "数据库查询出错";
        }

    }
    else {
        $_SESSION['message'] = "该用户名已存在";
    }

    
}

function loginUser($pdo, $username, $password) {

    $sql = "SELECT * FROM user_accounts WHERE username=?";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$username]); 

    if ($stmt->rowCount() == 1) {
        $userInfoRow = $stmt->fetch();
        return $userInfoRow;
    }

}

问题原因及解决办法

最可能的问题是数据库中password字段的长度不足:

  • PASSWORD_DEFAULT(默认使用bcrypt算法)生成的哈希字符串长度约为60个字符;
  • 若之前使用md5()/sha1(),对应的字段长度可能设置为VARCHAR(32)或VARCHAR(40),会导致存储哈希时被截断,从而使password_verify()验证失败。

解决步骤:

  1. 检查数据库user_accounts表的password字段类型,修改为VARCHAR(255)(留足余量适配未来哈希算法的变化);
  2. 修改字段长度后,重新注册用户(确保完整的哈希值被存储);
  3. 使用新注册的账号登录测试,验证password_verify()是否正常工作。

临时调试方法:在登录逻辑中添加echo strlen($passwordFromDB);,如果输出长度小于60,即可确认是字段截断导致的问题。

内容的提问来源于stack exchange,提问作者mynameiswadey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 19:04:56