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

Node与Python间AES加密解密互操作填充错误排查

Node.js AES加密后Python解密失败问题排查

Node.js AES密钥生成代码

const generateAesKey = () => {
    const { randomBytes } = require('node:crypto');

    randomBytes(32, (err, buf) => {
        if (err) throw err;
        return buf.toString('hex');
    });

}
const secretKey = generateAesKey(); 

密钥格式示例:491fb9719864f51e19a0705a3ef2de15cd91576d881cdc4bd4394bf7451ee404

Node.js AES加解密实现

const CryptoJS = require("crypto-js");

// 根据Tppaco的评论更新
const secretKey = CryptoJS.enc.Hex.parse("491fb9719864f51e19a0705a3ef2de15cd91576d881cdc4bd4394bf7451ee404");                                  

const encrypt = (plainText) => {
    const iv = CryptoJS.enc.Utf8.parse('BBBBBBBBBBBBBBBB');
    const encrypted = CryptoJS.AES.encrypt(plainText, CryptoJS.enc.Utf8.parse(secretKey), {
        iv: iv,
        mode: CryptoJS.mode.CBC,
    });
    return encrypted.toString();
}

const decrypt = (cipherText) => {
    const iv = CryptoJS.enc.Utf8.parse('BBBBBBBBBBBBBBBB');
    const decrypted = CryptoJS.AES.decrypt(cipherText, CryptoJS.enc.Utf8.parse(secretKey), {
        iv: iv,
        mode: CryptoJS.mode.CBC,
    });
    return CryptoJS.enc.Utf8.stringify(decrypted);
}

const en = encrypt("Text to be encrypted");
console.log(decrypt(en))

Node环境内加解密可正常运行,但将Node加密的数据拿到Python环境解密时出错。

Python端等效实现

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import base64
import json
import os
# CBC模式+固定IV

# key = os.urandom(32)                                 # 生成随机密钥

# 根据Tppaco的评论更新
key = bytes.fromhex('491fb9719864f51e19a0705a3ef2de15cd91576d881cdc4bd4394bf7451ee404')

data = 'Text to be encrypted'

# 固定IV
iv =  'BBBBBBBBBBBBBBBB'.encode('utf-8') # AES128需要16字节IV

def encrypt(data,key,iv):
        data= pad(data.encode(),16)
        cipher = AES.new(key,AES.MODE_CBC,iv)
        return base64.b64encode(cipher.encrypt(data))

def decrypt(enc,key,iv):
        enc = base64.b64decode(enc)
        cipher = AES.new(key, AES.MODE_CBC, iv)
        return unpad(cipher.decrypt(enc),16)

def lambda_handler(event, context):
    encrypted = encrypt(data,key,iv)
    print('加密后的CBC base64字符串 : ',encrypted.decode("utf-8", "ignore"))

    decrypted = decrypt(encrypted,key,iv)
    print('解密后的数据: ', decrypted.decode("utf-8", "ignore"))
    return {
        'statusCode': 200,
        'decrypted text': json.dumps(decrypted.decode("utf-8", "ignore"))
    }

错误信息

"errorMessage": "Padding is incorrect.",
"errorType": "ValueError",

核心需求:实现Node加密、Python解密,请问哪里操作有误?


问题排查与修复

1. 密钥重复解析导致值错误

Node代码中,你已经用CryptoJS.enc.Hex.parse将十六进制密钥转换成了原始字节对象,但在加密和解密时又重复调用CryptoJS.enc.Utf8.parse(secretKey),这会把已转换好的字节对象再次当作UTF-8字符串解析,导致密钥实际值与Python端不匹配,最终触发解密填充错误。

修复方案:直接使用已解析好的secretKey,去掉多余的Utf8.parse:

// 加密函数修改
const encrypted = CryptoJS.AES.encrypt(plainText, secretKey, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
});

// 解密函数修改
const decrypted = CryptoJS.AES.decrypt(cipherText, secretKey, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
});

2. 密钥生成函数的异步问题

原generateAesKey使用异步的randomBytes,但直接返回会得到undefined(异步操作未完成),如果需要生成有效密钥,改成同步方式:

const generateAesKey = () => {
    const { randomBytes } = require('node:crypto');
    const buf = randomBytes(32);
    return buf.toString('hex');
}
const secretKey = generateAesKey(); 

3. 填充方式一致性验证

CryptoJS默认使用PKCS7填充,Python的pycryptodome中pad函数默认也是PKCS7填充(第二个参数为块大小,符合PKCS7规则),这部分无需修改,密钥修复后即可匹配。

修复后的完整Node代码

const CryptoJS = require("crypto-js");

const secretKey = CryptoJS.enc.Hex.parse("491fb9719864f51e19a0705a3ef2de15cd91576d881cdc4bd4394bf7451ee404");                                  

const encrypt = (plainText) => {
    const iv = CryptoJS.enc.Utf8.parse('BBBBBBBBBBBBBBBB');
    const encrypted = CryptoJS.AES.encrypt(plainText, secretKey, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
    });
    return encrypted.toString();
}

const decrypt = (cipherText) => {
    const iv = CryptoJS.enc.Utf8.parse('BBBBBBBBBBBBBBBB');
    const decrypted = CryptoJS.AES.decrypt(cipherText, secretKey, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
    });
    return CryptoJS.enc.Utf8.stringify(decrypted);
}

const en = encrypt("Text to be encrypted");
console.log("加密后字符串:", en);
console.log("解密结果:", decrypt(en))

用修复后的Node代码加密得到的字符串,传入Python的decrypt函数即可正常解密,不会再出现填充错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:23:11