AES-128-CBC解密结果不一致:Python脚本与OpenSSL命令疑问
我来帮你拆解下为什么这两段代码的解密结果不一样——主要是几个细节没对齐,咱们一个个说:
1. OpenSSL命令没做解密操作!
你写的Bash命令用了openssl enc -aes-128-cbc,但这个命令默认是加密,要解密必须加-d参数。没加的话,你其实是在对输入的字符串做加密,和Python脚本的解密操作完全不是一回事,结果肯定不一样。
2. 密钥的处理逻辑不匹配
- Python里你直接传字符串
"abcdef1234567890"当密钥,AES库会把它转成UTF-8字节串(也就是b'abcdef1234567890')。 - 而OpenSSL的
-K(大写K)参数要求传入十六进制格式的密钥,如果你的密钥就是这个字符串的原始字节,应该用小写的-k参数(它会把字符串当作原始字节密钥),或者把Python的密钥也改成十六进制解析的形式:- 要么Python里把密钥改成
binascii.unhexlify("abcdef1234567890"),对应OpenSSL用-K abcdef1234567890; - 要么OpenSSL里把
-K换成-k,和Python的密钥逻辑对齐。
- 要么Python里把密钥改成
3. IV和加盐机制没对齐
Python里明确指定了固定IV(十六进制a1a1a1a1...解析后的字节),但你的Bash命令既没指定IV,也没禁用加盐。OpenSSL默认会启用加盐,自动生成随机IV,这会导致两边的IV完全不一致,解密结果自然对不上。
你需要给OpenSSL命令加两个参数:-nosalt(禁用加盐,因为Python里没加盐)和-iv a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1(指定和Python一样的IV)。
修正后的示例代码
保持密钥为原始字符串的版本
Python脚本:
from Crypto.Cipher import AES import binascii # 把密钥明确转成UTF-8字节 key = "abcdef1234567890".encode('utf-8') # 解析十六进制IV iv = binascii.unhexlify("a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1") decryptor = AES.new(key, AES.MODE_CBC, IV=iv) # 注意:如果你的密文是十六进制字符串,要先解析成字节,比如: # data_crypte = binascii.unhexlify("1234123412341234") # 这里假设密文是原始字节字符串,转成字节 data_crypte = "1234123412341234".encode('utf-8') clair = decryptor.decrypt(data_crypte) # 用with语句更安全 with open("output_file_py","wb") as f: f.write(clair)
对应的Bash命令:
# -d解密,-nosalt禁用加盐,-k指定原始字符串密钥,-iv指定IV echo -n "1234123412341234" | openssl enc -aes-128-cbc -d -nosalt -k "abcdef1234567890" -iv a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1 > output_file_bash
用十六进制密钥的版本
Python脚本调整密钥部分:
key = binascii.unhexlify("abcdef1234567890")
对应的Bash命令:
echo -n "1234123412341234" | openssl enc -aes-128-cbc -d -nosalt -K abcdef1234567890 -iv a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1 > output_file_bash
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

