You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

求助:CryptoJS AES 256加密内容在PHP中openssl_decrypt解密失败求示例代码

我之前帮不少人解决过这个问题,核心就是CryptoJS和PHP的AES配置没对齐——两边的密钥生成、IV、模式、填充必须完全一致才行。下面是经过实测的完整示例,你直接抄过去就能用:

CryptoJS AES 256加密 + PHP openssl_decrypt解密可行示例

1. 前端CryptoJS加密代码

先确保你引入了CryptoJS的库(可以用CDN或者本地文件),然后用这个加密函数:

// 先引入CryptoJS:<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

function encryptWithCryptoJS(plainText, secretKey) {
    // 生成16字节的随机IV(AES块大小固定128位,也就是16字节)
    const iv = CryptoJS.lib.WordArray.random(16);
    // 用CryptoJS默认的EVP_BytesToKey算法生成256位密钥(和PHP openssl的默认逻辑对齐)
    const keyParams = CryptoJS.EVP_BytesToKey(
        CryptoJS.enc.Utf8.parse(secretKey),
        iv,
        { keySize: 256/32, iterations: 1 }
    );
    // 执行加密:CBC模式+PKCS7填充(都是两边的默认值,显式写出来更稳妥)
    const encryptedResult = CryptoJS.AES.encrypt(
        plainText,
        keyParams.key,
        { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }
    );
    // 把IV和密文用冒号拼接成一个字符串返回,方便后端拆分
    return iv.toString(CryptoJS.enc.Base64) + ":" + encryptedResult.toString();
}

// 测试用例
const testText = "你好,这是要加密的测试内容!";
const myKey = "my_secure_key_2024";
const encryptedStr = encryptWithCryptoJS(testText, myKey);
console.log("加密后内容:", encryptedStr);

2. 后端PHP解密代码

把前端传过来的加密字符串丢进这个函数就能解密:

function decryptWithOpenSSL($encryptedStr, $secretKey) {
    // 拆分IV和密文(前端是用冒号拼接的)
    list($ivBase64, $ciphertextBase64) = explode(":", $encryptedStr, 2);
    
    // 解码Base64格式的IV和密文
    $iv = base64_decode($ivBase64);
    $ciphertext = base64_decode($ciphertextBase64);
    
    // 用openssl_pbkdf2实现和CryptoJS一致的EVP_BytesToKey密钥生成逻辑
    $generatedKey = openssl_pbkdf2($secretKey, $iv, 32, 1, 'md5');
    
    // 执行解密:AES-256-CBC模式,记得传OPENSSL_RAW_DATA参数
    $decryptedText = openssl_decrypt(
        $ciphertext,
        'aes-256-cbc',
        $generatedKey,
        OPENSSL_RAW_DATA,
        $iv
    );
    
    // 如果解密失败,可以打印错误信息排查
    if ($decryptedText === false) {
        die("解密出错:" . openssl_error_string());
    }
    
    return $decryptedText;
}

// 测试用例
$encryptedStr = "这里替换成前端输出的加密字符串";
$myKey = "my_secure_key_2024";
echo "解密后内容:" . decryptWithOpenSSL($encryptedStr, $myKey);

必须注意的几个关键点

  • 密钥生成逻辑:CryptoJS默认用EVP_BytesToKey算法生成密钥,PHP必须用openssl_pbkdf2完全匹配参数(32字节密钥、1次迭代、MD5哈希),这是最容易踩坑的地方!
  • IV的传递:IV必须是随机的,而且加密后要和密文一起传给后端——解密必须用同一个IV,千万不能硬写死IV。
  • 填充和模式:两边都用CBC模式+PKCS7填充,这是CryptoJS和PHP openssl的默认配置,但显式写出来更不容易出错。
  • 调试技巧:如果还是返回false,一定要用openssl_error_string()打印具体错误,比如密钥长度不对、IV格式错误之类的,很快就能定位问题。

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

火山引擎 最新活动