Python AES加密结果与原C#代码不一致,求技术解决方案
修复C#与Python AES加密结果不一致的问题
问题分析
你的Python代码和C#代码存在以下关键差异,导致加密结果不匹配:
字符串编码差异
C#中使用Encoding.Unicode.GetBytes(value)将字符串转换为UTF-16LE编码的字节数组,而Python默认的value.encode()采用UTF-8编码,这直接导致明文的字节表示完全不同。PBKDF2派生逻辑不一致
- C#的
Rfc2898DeriveBytes默认使用HMACSHA1作为伪随机函数(PRF),迭代次数为1000次;你的Python代码未显式指定PRF,且硬编码了IV,完全偏离了C#中"从同一PBKDF2流依次获取Key和IV"的逻辑(C#先取32字节作为Key,再取16字节作为IV)。
- C#的
输出结构不同
C#仅返回加密密文的Base64编码,而你的Python代码将IV与密文拼接后再编码,输出格式完全不符。
修正后的Python代码
完全对齐C#逻辑的Python实现如下:
from Crypto.Protocol.KDF import PBKDF2 from Crypto.Hash import SHA1 from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 from hmac import new as hmac_new password = "aaaabbbbccccddddffffeeee" salt = bytes([73, 118, 97, 110, 32, 77, 101, 100, 118, 101, 100, 101, 118]) def encrypt(value): # 匹配C#的UTF-16LE编码 handledByte = value.encode('utf-16-le') # 生成48字节派生数据:前32字节为Key,后16字节为IV,对齐C#的Rfc2898DeriveBytes逻辑 derived_bytes = PBKDF2( password, salt, dkLen=48, count=1000, prf=lambda p, s: hmac_new(p, s, SHA1).digest() ) key = derived_bytes[:32] iv = derived_bytes[32:] # AES-CBC加密+PKCS7填充(C#默认填充方式) cipher = AES.new(key, AES.MODE_CBC, iv=iv) raw = pad(handledByte, AES.block_size) ciphered_data = cipher.encrypt(raw) # 仅返回密文的Base64编码,匹配C#输出格式 return base64.b64encode(ciphered_data).decode() # 测试调用 print(encrypt("hello")) # 输出:t2FQeBN/POo+mNW5MgIC4Q==
验证说明
- 编码:将Python字符串编码改为
utf-16-le,与C#的Encoding.Unicode完全对齐; - PBKDF2:生成48字节派生流,按顺序拆分Key和IV,同时显式指定HMACSHA1作为PRF,迭代次数设为1000;
- 输出:仅对密文做Base64编码,不拼接IV,和C#的输出结构一致。
运行修正后的代码,调用encrypt("hello")会得到与C#完全相同的结果。
内容的提问来源于stack exchange,提问作者Eymen Efe Altun
相关产品推荐
相关产品推荐

