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

如何用JavaScript解密PHP加密的AES-256-CBC字符串(不修改PHP代码)

解决Node.js解密PHP生成的AES-256-CBC密文时的"Invalid key length"错误(无需修改PHP代码)

可以不用修改PHP代码完成解密,问题出在PHP和Node.js对密钥的处理逻辑差异上:

  • PHP的openssl_encrypt在使用AES-256-CBC时,如果传入的密钥长度不符合32字节(256位)要求,会自动用NULL字节(\x00)填充到32字节;如果密钥超过32字节,则直接截断到前32字节。
  • Node.js的crypto模块则要求密钥长度严格匹配算法要求,不会自动处理,所以才会抛出"Invalid key length"错误。

解决步骤

  1. 确认PHP加密时使用的原始密钥和IV(这两个参数必须和PHP端完全一致)
  2. 在Node.js中按照PHP的逻辑处理密钥和IV:
    • 密钥:调整为32字节,不足补\x00,过长则截断前32字节
    • IV:调整为16字节(AES-CBC块大小),不足补\x00,过长则截断前16字节
  3. 用处理后的密钥和IV执行解密

Node.js示例代码

const crypto = require('crypto');

function decryptPhpAes(encryptedBase64, rawIv, rawKey) {
    // 处理密钥:匹配PHP的自动补全/截断逻辑
    let keyBuffer = Buffer.from(rawKey, 'utf8');
    if (keyBuffer.length !== 32) {
        keyBuffer = keyBuffer.length < 32 
            ? Buffer.concat([keyBuffer, Buffer.alloc(32 - keyBuffer.length, 0)])
            : keyBuffer.slice(0, 32);
    }

    // 处理IV:匹配PHP的自动补全/截断逻辑
    let ivBuffer = Buffer.from(rawIv, 'utf8');
    if (ivBuffer.length !== 16) {
        ivBuffer = ivBuffer.length < 16
            ? Buffer.concat([ivBuffer, Buffer.alloc(16 - ivBuffer.length, 0)])
            : ivBuffer.slice(0, 16);
    }

    // 执行解密
    const decipher = crypto.createDecipheriv('aes-256-cbc', keyBuffer, ivBuffer);
    let decrypted = decipher.update(encryptedBase64, 'base64', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

// 替换为你的实际参数
const encryptedStr = 'Ky27sjhxUY7BFoscEgyFToxRDAsARzRFgQBIApbPmjQ=';
const phpIv = '这里填PHP加密用的IV';
const phpKey = '这里填PHP加密用的密钥';

console.log(decryptPhpAes(encryptedStr, phpIv, phpKey));

注意事项

  • 必须确保PHP和Node.js使用的字符编码一致(通常都是UTF-8)
  • 如果PHP端加密时使用了OPENSSL_RAW_DATA选项,密文会是原始二进制而不是Base64,此时解密时要去掉base64参数,改用binary或者直接传入Buffer

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:17:31