C#加密字符串后Python解密失败(疑似IV推导错误)
C# AES加密字符串的Python解密故障排查与修复
我用以下C#代码实现字符串AES加密,但对应的Python解密代码无法正常工作,疑似IV推导逻辑错误。需要调整Python代码,使其能正确解密C#加密后的内容。
C# 加密代码
public string Encrypt(string plainText) { // Transformar la clave de encriptación de Base64 a bytes var base64Key = "MiEncryptKey=".Replace('_', '/').Replace('-', '+'); var keyBytes = Convert.FromBase64String(base64Key); // Derivar la clave y el IV usando Rfc2898DeriveBytes con SHA256 var salt = Encoding.UTF8.GetBytes("AgenteSalt"); var pdb = new Rfc2898DeriveBytes(keyBytes, salt, 1000); var key = pdb.GetBytes(32); var iv = pdb.GetBytes(16); // Configurar el cifrador AES en modo CBC con PKCS7 padding using (var aes = new RijndaelManaged()) { aes.KeySize = 256; aes.BlockSize = 128; aes.Padding = PaddingMode.PKCS7; aes.Mode = CipherMode.CBC; aes.Key = key; aes.IV = iv; // Encriptar el texto using (var ms = new MemoryStream()) { using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { var bytes = Encoding.UTF8.GetBytes(plainText); cs.Write(bytes, 0, bytes.Length); cs.Close(); } var encrypted = ms.ToArray(); // Codificar el resultado en Base64 return Convert.ToBase64String(encrypted); } } }
原Python解密代码(无法正常工作)
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes import base64 class Decryptor: def __init__(self, base64_key, salt=b"MiSalt"): self.base64_key = base64_key.replace('_', '/').replace('-', '+') self.encryption_key = base64.b64decode(self.base64_key) self.salt = salt self.iterations = 1000 def _get_cipher(self): # Usando SHA1 aquí para coincidir con el algoritmo de hash de C# kdf = PBKDF2HMAC( algorithm=hashes.SHA1(), length=32, salt=self.salt, iterations=self.iterations, backend=default_backend() ) key = kdf.derive(self.encryption_key) iv = key[:16] return Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) def decrypt(self, cipher_text): cipher = self._get_cipher() decryptor = cipher.decryptor() ct = base64.b64decode(cipher_text) decrypted = decryptor.update(ct) + decryptor.finalize() return self._unpad(decrypted) def _unpad(self, s): pad_size = s[-1] if pad_size > 16: raise ValueError("Invalid padding") return s[:-pad_size]
核心问题分析
- Salt不匹配:C#代码中使用的salt是
"AgenteSalt"的UTF-8字节,而Python代码错误使用了b"MiSalt",直接导致密钥和IV的推导结果完全不同。 - IV推导逻辑错误:C#中
Rfc2898DeriveBytes是连续生成字节流——先取32字节作为密钥,再从同一流的下一个位置取16字节作为IV;但Python代码错误地将密钥的前16字节当作IV,和C#逻辑完全不符。 - 注:C#的
Rfc2898DeriveBytes默认使用SHA1哈希算法,Python代码中这部分是正确的。
修正后的Python解密代码
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes import base64 class Decryptor: def __init__(self, base64_key): self.base64_key = base64_key.replace('_', '/').replace('-', '+') self.encryption_key = base64.b64decode(self.base64_key) # 匹配C#中的salt:"AgenteSalt"的UTF-8字节 self.salt = b"AgenteSalt" self.iterations = 1000 def _get_cipher(self): # 生成足够长度的派生字节:32字节key + 16字节iv = 48字节 kdf = PBKDF2HMAC( algorithm=hashes.SHA1(), length=48, salt=self.salt, iterations=self.iterations, backend=default_backend() ) derived_bytes = kdf.derive(self.encryption_key) key = derived_bytes[:32] # 前32字节作为密钥,和C#一致 iv = derived_bytes[32:] # 后16字节作为IV,和C#逻辑匹配 return Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) def decrypt(self, cipher_text): cipher = self._get_cipher() decryptor = cipher.decryptor() ct = base64.b64decode(cipher_text) decrypted = decryptor.update(ct) + decryptor.finalize() return self._unpad(decrypted).decode('utf-8') def _unpad(self, s): # PKCS7解包逻辑:最后一个字节的值就是填充长度 pad_size = s[-1] if pad_size < 1 or pad_size > 16: raise ValueError("Invalid padding") return s[:-pad_size]
修正说明
- 同步salt值为
b"AgenteSalt",和C#保持一致。 - 修改KDF的
length参数为48,一次性生成足够的派生字节,再拆分出32字节密钥和16字节IV,完全匹配C#的GetBytes(32)+GetBytes(16)逻辑。 - 解密后增加
decode('utf-8'),将字节流转换为字符串。 - 优化解包逻辑的校验条件,确保符合PKCS7规范。
内容的提问来源于stack exchange,提问作者Binapps
相关产品推荐
相关产品推荐

