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

MySQL AES加密密码与PHP匹配失败,求正确实现方案

MySQL AES加密与PHP验证匹配失败的解决方案

问题分析

你的代码存在两个核心错误:

  1. SQL语法错误:AES_DECRYPT函数的参数括号书写错误,正确格式应为AES_DECRYPT(PASSWORD, 'test'),多余的右括号会导致SQL执行异常,获取到的密码值为空或错误。
  2. 逻辑错误:你将MySQL解密后的明文密码,与password_hash生成的单向哈希值做对比——password_hash是生成不可逆的哈希串,而AES是对称加密的明文还原逻辑,两者不属于同一类加密体系,自然无法匹配。

正确实现方案

方案1:修复AES对称加密的验证逻辑

如果坚持使用MySQL的AES加密,可通过以下两种方式实现匹配:

方式A:PHP获取MySQL解密后的明文直接对比

修正SQL语法与PHP逻辑:

<?php
$conn = mysqli_connect('localhost', 'test', 'test123', 'test');
// 修正AES_DECRYPT的语法,同时用UNHEX还原存储的十六进制密文
$sql = "SELECT user_id, AES_DECRYPT(UNHEX(PASSWORD), 'test') AS decrypted_password FROM test WHERE user_id = 'Jace'";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_array($result);

// 直接对比明文密码
if ($row['decrypted_password'] === 'Jace123') {
    echo "right";
} else {
    echo "wrong";
}
?>

注:因为你存储的是HEX(AES_ENCRYPT(...))生成的十六进制字符串,解密前需要用UNHEX还原为二进制数据。

方式B:PHP端生成兼容MySQL的AES密文后对比

PHP使用openssl_encrypt实现与MySQL默认AES-128-ECB模式兼容的加密:

<?php
$conn = mysqli_connect('localhost', 'test', 'test123', 'test');
$plainPassword = 'Jace123';
$key = 'test';

// 兼容MySQL的AES加密规则:密钥补全到16字节,使用ECB模式
$key = str_pad($key, 16, "\0");
$encrypted = openssl_encrypt($plainPassword, 'AES-128-ECB', $key, OPENSSL_RAW_DATA);
$encryptedHex = bin2hex($encrypted);

// 查询库中存储的密文进行对比
$sql = "SELECT password FROM test WHERE user_id = 'Jace'";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_array($result);

if ($row['password'] === $encryptedHex) {
    echo "right";
} else {
    echo "wrong";
}
?>

方案2:使用更安全的单向哈希存储密码

强烈推荐:对称加密存储密码存在安全风险(密钥泄露后所有密码可被解密),行业标准做法是使用单向哈希算法,比如PHP内置的password_hash和password_verify:

步骤1:插入数据时生成哈希值存入

<?php
$conn = mysqli_connect('localhost', 'test', 'test123', 'test');
$plainPassword = 'Jace123';
// 生成不可逆的密码哈希
$hashPassword = password_hash($plainPassword, PASSWORD_DEFAULT);

// 使用预处理语句避免SQL注入
$sql = "INSERT INTO test (user_id, password) VALUES ('Jace', ?)";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "s", $hashPassword);
mysqli_stmt_execute($stmt);
?>

步骤2:验证时用password_verify对比

<?php
$conn = mysqli_connect('localhost', 'test', 'test123', 'test');
$inputPassword = 'Jace123';

$sql = "SELECT password FROM test WHERE user_id = 'Jace'";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_array($result);

// 用password_verify验证,不可直接用==对比哈希值
if (password_verify($inputPassword, $row['password'])) {
    echo "right";
} else {
    echo "wrong";
}
?>

问题总结

  1. SQL语句的语法错误导致解密失败,是验证不通过的直接原因;
  2. 混淆了对称加密与单向哈希的逻辑,错误地将两种不同加密体系的结果做对比;
  3. 对称加密存储密码存在安全隐患,建议优先采用单向哈希方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 18:20:27