将JavaScript加密算法转Python遇AES密钥长度错误求助
解决AES密钥长度错误:CryptoJS转Python加密代码修正
问题根源
你碰到的ValueError: Incorrect AES key length (48 bytes)是因为错误地将PBKDF2生成的48字节完整数据作为AES密钥传入,但原JavaScript代码明确只取了前32字节作为AES密钥,剩余16字节用作初始化向量(IV)。
修正后的Python代码
from Crypto.Protocol.KDF import PBKDF2 from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 def enc(a): # 生成48字节派生数据,和JS的keySize=48/4=12对应(每个Word占4字节) derived_data = PBKDF2("lrvq/wyDf6tqhxvg8NuIDQ==", "Ivan Medvedev", dkLen=48, count=1000) # 截取前32字节作为AES-256密钥 aes_key = derived_data[:32] # 截取后16字节作为CBC模式的IV iv = derived_data[32:] # 按UTF-16LE编码明文,和JS保持一致 plaintext_bytes = a.encode('utf-16le') # AES-CBC加密,使用PKCS7填充(CryptoJS默认填充方式) cipher = AES.new(aes_key, AES.MODE_CBC, iv) encrypted_bytes = cipher.encrypt(pad(plaintext_bytes, AES.block_size)) # CryptoJS的AES.encrypt输出为密文的Base64字符串,而非十六进制 return base64.b64encode(encrypted_bytes).decode('utf-8') print(enc("Cat"))
核心修正说明
- 密钥截取:AES-256需要32字节密钥,原JS代码从PBKDF2生成的48字节中取前32字节,剩余16字节正好符合CBC模式IV的长度要求。
- 输出格式:原JS中
encrypted.toString()输出的是密文的Base64编码,而非十六进制,因此Python代码要改用base64.b64encode处理加密结果。 - PBKDF2参数:你设置的
dkLen=48是正确的,对应JS里keySize: 48/4=12(CryptoJS的keySize以Word为单位,每个Word4字节)。
内容的提问来源于stack exchange,提问作者farhan jatt
相关产品推荐
相关产品推荐

