.NET 7 AES解密出现‘填充无效且无法移除’错误求助
问题分析与修复方案
你的问题出在解密过程中没有使用从密文中提取的正确IV,而是误用了Aes实例自动生成的新IV,这直接导致解密乱码和填充错误。另外还有细节需要补全,具体修复如下:
核心错误点
- IV使用错误:
Decrypt方法里,你调用aesAlg.CreateDecryptor(key, aesAlg.IV)时,aesAlg.IV是Aes实例新生成的随机值,不是加密时用的那个。必须传入从密文中分离出的cbcCiphertext.IV。 - 未显式指定加密模式:加密时设置了
CipherMode.CBC,解密时最好显式同步设置,避免因系统默认值变化引发问题。
修复后的完整代码
public class AesEncryption { private static byte[] key = new byte[32] { /* 你的256位密钥 */ }; // 256-bit key public static string Encrypt(string plaintext) { using (Aes aesAlg = Aes.Create()) { var iv = aesAlg.IV; aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; ICryptoTransform encryptor = aesAlg.CreateEncryptor(key, iv); byte[] encryptedBytes; using (var msEncrypt = new MemoryStream()) { using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (var streamWriter = new StreamWriter(csEncrypt)) { streamWriter.Write(plaintext); } } encryptedBytes = msEncrypt.ToArray(); } return new AesCbcCiphertext(iv, encryptedBytes).ToString(); } } public static string Decrypt(string ciphertext) { var cbcCiphertext = AesCbcCiphertext.FromBase64String(ciphertext); using (Aes aesAlg = Aes.Create()) { aesAlg.Mode = CipherMode.CBC; // 与加密模式保持一致 aesAlg.Padding = PaddingMode.PKCS7; // 使用从密文中提取的正确IV ICryptoTransform decryptor = aesAlg.CreateDecryptor(key, cbcCiphertext.IV); using (var msDecrypt = new MemoryStream(cbcCiphertext.CiphertextBytes)) { using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (var streamReader = new StreamReader(csDecrypt)) { return streamReader.ReadToEnd(); } } } } } } internal class AesCbcCiphertext { public byte[] IV { get; } public byte[] CiphertextBytes { get; } public static AesCbcCiphertext FromBase64String(string data) { var dataBytes = Convert.FromBase64String(data); return new AesCbcCiphertext( dataBytes.Take(16).ToArray(), dataBytes.Skip(16).ToArray() ); } public AesCbcCiphertext(byte[] iv, byte[] ciphertextBytes) { IV = iv; CiphertextBytes = ciphertextBytes; } public override string ToString() { var total = IV.Concat(CiphertextBytes).ToArray(); return Convert.ToBase64String(total); // 优化:直接使用已拼接的数组 } }
额外说明
- IV在AES-CBC模式中至关重要:它能让相同明文用同一密钥加密时生成不同密文,防止模式重复被攻击者利用。解密必须使用和加密完全一致的IV,否则无法正确还原明文,甚至触发填充错误。
- 硬编码固定IV时正常,是因为加密和解密用了同一个固定值,但这种做法不安全,你使用可变IV的思路是正确的,只是解密时IV用错了。
内容的提问来源于stack exchange,提问作者Yohancef Chin
相关产品推荐
相关产品推荐

