TypeScript AES解密逻辑转Python遇错误输出,求排查问题
解决CryptoJS AES加密转Python解密的错误问题
你的Python代码和CryptoJS的实现存在几个核心差异,导致解密失败,具体问题和修正方案如下:
关键问题点
- 密钥生成逻辑不同:CryptoJS调用
AES.encrypt(data, key)时,若传入的是字符串密钥,会自动通过OpenSSL的EVP_BytesToKey算法(基于MD5哈希)生成实际的AES密钥和IV;而你的Python代码直接使用原始字节作为密钥,未执行该推导步骤。 - 加密格式未解析:CryptoJS的加密输出是OpenSSL兼容的格式,Base64解码后开头是
salted__(对应字节0x53616c7465645f5f),后面跟着8字节salt和实际密文;你的Python代码直接把整个解码后的数据当作密文,未拆分salt部分。 - IV未正确生成:CryptoJS通过EVP_BytesToKey结合salt生成IV,你的Python代码未指定IV,默认使用全0字节,导致解密时数据不匹配。
- 填充方式未处理:CryptoJS默认使用PKCS7填充,解密后需要去除填充字节,你的代码未做这一步。
修正后的Python代码
import base64 from Crypto.Cipher import AES from Crypto.Hash import MD5 from Crypto.Util.Padding import unpad def evp_bytes_to_key(password: bytes, salt: bytes, key_len: int = 32, iv_len: int = 16) -> tuple[bytes, bytes]: """实现OpenSSL的EVP_BytesToKey算法,生成密钥和IV""" key = b"" iv = b"" while len(key) < key_len or len(iv) < iv_len: hash_data = MD5.new() hash_data.update(key + password + salt) digest = hash_data.digest() key += digest iv += digest[len(key)-key_len:] if len(key) > key_len else digest return key[:key_len], iv[:iv_len] # 替换为CryptoJS生成的加密字符串 encrypted_data = "U2FsdGVkX198Jnuf6hHeS1bDSP5mrn/+ciFwd5l4Yiw=" # 替换为CryptoJS中使用的原始密钥字符串 password = "d76d312b4647849345285b7c11dbb9e6" # 解码Base64数据 decoded = base64.b64decode(encrypted_data) # 拆分salt和密文(前8字节是`salted__`标记,后8字节是salt) salt = decoded[8:16] ciphertext = decoded[16:] # 生成密钥和IV key, iv = evp_bytes_to_key(password.encode('utf-8'), salt) # 初始化AES解密器(CBC模式,对应CryptoJS默认) cipher = AES.new(key, AES.MODE_CBC, iv=iv) # 解密并去除PKCS7填充 decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size) print("Decrypted message:", decrypted.decode('utf-8'))
验证说明
运行上述代码,输入CryptoJS生成的加密字符串和原始密钥,将得到正确的明文Data to be encrypted。核心是还原了CryptoJS底层的密钥/IV生成逻辑,以及正确解析了它的加密输出格式。
内容的提问来源于stack exchange,提问作者Gulineu
相关产品推荐
相关产品推荐

