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

PHP使用openssl_encrypt加密的字符串无法在MySQL中AES_DECRYPT解密

问题原因及解决方法

核心问题1:密文编码格式不匹配

PHP侧openssl_encrypt默认返回base64编码后的加密字符串,但MySQL的AES_DECRYPT函数要求输入的是原始二进制密文,你直接把base64字符串传入解密函数,肯定无法得到正确结果。

核心问题2:密钥长度不匹配

AES-256算法要求密钥长度为32字节:

  • PHP侧hash("sha256", xxx)默认返回64个字符的十六进制字符串(总长度64字节),openssl_encrypt会自动截断前32字节作为实际密钥使用
  • 你之前在MySQL侧直接把SHA2返回的64字节十六进制字符串作为密钥,和PHP实际使用的密钥不一致

核心问题3:加密结果输出格式不匹配

你之前测试MySQL加密结果不对,是因为AES_ENCRYPT返回的是原始二进制数据,直接转字符串或者查看显示为blob,需要用TO_BASE64()转成base64编码才能和PHP输出的加密结果对比。

正确可运行的代码

解密代码

SET block_encryption_mode = 'aes-256-cbc';
-- 取SHA2结果前32字节作为密钥,和PHP侧实际使用的密钥对齐
SET @key_str = LEFT(SHA2('Pn6nK7Gs9r',256), 32);
SET @init_vector = '98awg9X7SiI3jxp3';
SET @encrypted = 'Xq1CcrpteSqcybePun+6pQ==';

-- 先对密文做base64解码,再解密转字符串
SELECT CAST(AES_DECRYPT(FROM_BASE64(@encrypted), @key_str, @init_vector) AS CHAR(100)) AS decrypted;

运行后decrypted字段值就是你预期的test。

加密验证代码

SET block_encryption_mode = 'aes-256-cbc';
SET @key_str = LEFT(SHA2('Pn6nK7Gs9r',256), 32);
SET @init_vector = '98awg9X7SiI3jxp3';
SET @string = 'test';

-- 加密后转base64,和PHP输出结果一致
SELECT TO_BASE64(AES_ENCRYPT(@string, @key_str, @init_vector)) AS encrypted;

运行后encrypted字段值就是你预期的Xq1CcrpteSqcybePun+6pQ==。

额外优化建议

如果要避免后续密钥处理的歧义,建议PHP侧生成密钥时直接返回原始二进制,两边处理更统一:

// 第三个参数传true,直接返回32字节的原始二进制哈希值
$enc_key = hash("sha256", "Pn6nK7Gs9r", true);

对应MySQL侧密钥处理改为:

-- 把十六进制的SHA2结果转成32字节二进制
SET @key_str = UNHEX(SHA2('Pn6nK7Gs9r',256));

这种方式更符合AES算法的密钥规范,也不会出现截断的隐含逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:57:04