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

PHP新手求助:SHA512加密后登录验证失败问题

登录时SHA512加密密码验证失败的问题排查与解决

嘿,作为PHP新手能主动放弃不安全的MD5,选择SHA512加密密码,这点必须给你点个赞!不过遇到登录验证失败的问题别着急,咱们一步步来排查:

先把你贴的核心代码整理清楚:

登录核心代码

$username = mysqli_real_escape_string($con,$username); 
$password = stripslashes($_REQUEST['password']); 
$password = mysqli_real_escape_string($con,$password); 
$password = hash('sha512',$password); 

//Checking is user existing in the database or not 
$query = "SELECT * FROM `users` WHERE username='$username' AND password='".$password."'"; 
$result = mysqli_query($con,$query) or die(mysql_error()); 
$rows = mysqli_num_rows($result); 
$row = mysqli_fetch_array($result); 
if($rows==1){
    // 登录成功逻辑
}

注册核心代码

//Strip & Escape PW 
$password = stripslashes($_REQUEST['password']); 
$password = mysqli_real_escape_string($con,$password); 

$sql_u = "SELECT username FROM users WHERE username='$username'"; 
$sql_e = "SELECT email FROM users WHERE email='$email'"; 
$res_u = mysqli_query($con, $sql_u); 
$res_e = mysqli_query($con, $sql_e); 

if (mysqli_num_rows($res_u) > 0) { 
    $name_error = "Sorry... username already taken"; 
} else if(mysqli_num_rows($res_e) > 0){ 
    $email_error = "Sorry... email already taken"; 
} else{ 
    $query = "INSERT INTO users (username, email, password) VALUES ('$username', '$email', '".hash('sha512',$password)."')"; 
    $results = mysqli_query($con, $query); 
    echo 'You Have Registered Successfully!<br>';
}

最可能的问题:数据库字段长度不够

SHA512加密后的哈希值是128个十六进制字符,如果你的users表中password字段的长度设置得不够(比如设成了VARCHAR(64)或者更短),存储时就会自动截断哈希值,导致登录时生成的完整哈希和数据库里截断后的哈希不匹配——这是新手最容易踩的坑!

解决方法:把数据库中password字段的类型改成VARCHAR(128)或者TEXT,然后重新注册一个用户测试登录。

次要问题:密码处理逻辑的冗余与风险

你现在用stripslashes和mysqli_real_escape_string处理密码其实没必要,甚至可能出问题:

  • stripslashes是为了处理早年PHP开启magic_quotes_gpc时自动添加的反斜杠,但现在这个配置早就被废弃了,用它反而会意外修改密码(比如用户密码里真的有反斜杠,会被去掉)
  • mysqli_real_escape_string是用来防止SQL注入的,但直接拼接SQL语句本身就不安全,应该用预处理语句替代

更推荐的安全方案:用PHP原生密码函数

其实SHA512也不是最安全的选择——它是快速哈希算法,容易被暴力破解。PHP自带的password_hash()和password_verify()才是最佳实践,它们会自动加盐,而且哈希算法会随着PHP版本更新自动升级,示例代码如下:

注册时的写法

// 直接获取原始密码,不需要额外转义
$password = $_REQUEST['password'];
// 生成安全的哈希密码,PASSWORD_DEFAULT会自动使用当前最安全的算法(目前是bcrypt)
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);

// 用预处理语句插入数据,彻底避免SQL注入
$stmt = mysqli_prepare($con, "INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
mysqli_stmt_bind_param($stmt, "sss", $username, $email, $hashedPassword);
mysqli_stmt_execute($stmt);

echo 'You Have Registered Successfully!<br>';

登录时的写法

$username = $_REQUEST['username'];
$password = $_REQUEST['password'];

// 用预处理语句查询用户的哈希密码
$stmt = mysqli_prepare($con, "SELECT password FROM users WHERE username = ?");
mysqli_stmt_bind_param($stmt, "s", $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $hashedPassword);
mysqli_stmt_fetch($stmt);

// 用password_verify验证密码,不需要手动哈希
if (password_verify($password, $hashedPassword)) {
    // 登录成功逻辑
    echo "登录成功!";
} else {
    // 密码错误
    echo "用户名或密码无效!";
}

注意:用password_hash()生成的哈希最长是255个字符,所以数据库password字段要设成VARCHAR(255)。

你可能遗漏的要点

你之前参考的文章里的验证逻辑是对的,但前提是数据库里存储的是完整的哈希值——你大概率是忽略了数据库字段长度的问题,导致哈希被截断,这才是验证失败的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:41:44