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

CryptoJS加密后PHP openssl_decrypt返回Null的问题排查

问题原因及解决方案

你的解密失败核心原因是前后端密钥处理逻辑不匹配,同时存在算法参数错误,以下是具体分析和修复方案:

问题分析

  1. 密钥处理差异:前端CryptoJS默认会把传入的字符串密钥当作"密码",通过PBKDF2算法推导实际AES密钥;但后端直接将字符串当作原始AES密钥使用,导致双方密钥完全不一致。
  2. 算法参数错误:你使用的key是32位十六进制字符串(对应16字节/128位),但后端指定了AES-256-CBC(需要32字节密钥),openssl会自动补全密钥,进一步加剧不匹配。

方案一:直接使用原始密钥(推荐)

调整前后端代码,统一使用原始十六进制密钥,跳过PBKDF2推导:

前端修改代码

var a = $('#email').val();
// 将十六进制key转换为CryptoJS可识别的WordArray
var key = CryptoJS.enc.Hex.parse("6fa979f20126cb08aa645a8f495f6d85");
// 将iv字符串转换为WordArray(确保iv是16字节,符合AES块大小)
var iv = CryptoJS.enc.Utf8.parse("I8zyA4lVhMCaJ5Kg");

var encrypted = CryptoJS.AES.encrypt(a, key, { 
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7 // 与openssl默认填充方式一致
});
// 仅取密文的Base64编码
encrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
$('#email').val(encrypted);

后端修改代码

function cryptoJsAesDecrypt($enc_text){
    // 匹配前端的AES-128算法(16字节密钥)
    $encryptionMethod = "AES-128-CBC";
    // 将十六进制key转换为原始字节
    $key = hex2bin("6fa979f20126cb08aa645a8f495f6d85");
    $iv = "I8zyA4lVhMCaJ5Kg";
    
    // 校验iv长度(必须16字节)
    if (strlen($iv) != 16) {
        die("IV长度必须为16字节");
    }
    
    $ciphertext_dec = base64_decode($enc_text);
    // OPENSSL_RAW_DATA对应前端的原始字节输出
    $decrypted = openssl_decrypt($ciphertext_dec, $encryptionMethod, $key, OPENSSL_RAW_DATA, $iv);

    return $decrypted;
}

方案二:保留CryptoJS默认PBKDF2逻辑

如果坚持使用前端原有密钥处理方式,需要传递CryptoJS生成的salt给后端,用于推导一致的密钥:

前端修改代码

var a = $('#email').val();
var key = "6fa979f20126cb08aa645a8f495f6d85";
var iv =  "I8zyA4lVhMCaJ5Kg";

var encrypted = CryptoJS.AES.encrypt(a, key, {iv:iv});
// 同时传递密文和salt(用分隔符拼接)
var encryptedData = encrypted.ciphertext.toString(CryptoJS.enc.Base64) + '|' + encrypted.salt.toString(CryptoJS.enc.Base64);
$('#email').val(encryptedData);

后端修改代码

function cryptoJsAesDecrypt($enc_text){
    // 拆分密文和salt
    list($ciphertext_b64, $salt_b64) = explode('|', $enc_text);
    
    $encryptionMethod = "AES-256-CBC";
    $password = "6fa979f20126cb08aa645a8f495f6d85";
    $iv =  "I8zyA4lVhMCaJ5Kg";
    
    $ciphertext_dec = base64_decode($ciphertext_b64);
    $salt = base64_decode($salt_b64);
    
    // 模拟CryptoJS的PBKDF2推导:SHA-1哈希、1000次迭代、32字节密钥
    $key = hash_pbkdf2('sha1', $password, $salt, 1000, 32, true);
    
    $decrypted = openssl_decrypt($ciphertext_dec, $encryptionMethod, $key, OPENSSL_RAW_DATA, $iv);

    return $decrypted;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:34:59