.NET6迁移后AES加解密出现Padding is invalid填充错误问题咨询
AES从.NET Framework 4.7.2迁移至.NET 6解密异常问题解决指南
核心故障原因
- 字符编码默认值不兼容:.NET Framework中
Encoding.Default对应系统本地代码页(中文环境通常为GB2312/GBK),.NET 6中Encoding.Default统一为UTF-8,若密钥、IV、明文转字节数组时依赖默认编码,会导致两端字节序列不一致,触发填充校验失败、长文本截断。 - 加密参数隐式变更:若代码未显式声明AES的模式、填充方式、块大小、密钥长度,跨版本运行时可能出现默认参数不一致,直接导致解密逻辑不匹配。
- Base64处理逻辑差异:.NET 6中
Convert.FromBase64String对非法字符的校验更严格,若密文字符串包含传输过程中产生的换行、空格等冗余字符,.NET Framework会自动忽略,.NET 6会生成错误的密文字节数组。 - 内存处理逻辑优化带来的差异:.NET 6加密类底层使用Span优化内存分配,若解密时自定义缓冲区长度计算错误、未完整读取加密流,会导致尾部填充字节被截断,触发填充错误。
解决方案
- 显式声明所有加密参数,禁止依赖默认值
using (Aes aes = Aes.Create()) { // 所有参数和.NET Framework端配置完全对齐 aes.KeySize = 256; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; // 优先直接用字节数组赋值密钥、IV,避免字符串转码误差 aes.Key = confirmedKeyBytes; aes.IV = confirmedIVBytes; }
- 统一字符编码,禁止使用
Encoding.Default
所有涉及字符串转字节数组的逻辑,统一显式指定编码,和服务端完全对齐。如果需要使用GBK等非UTF-8编码,需先引入System.Text.Encoding.CodePagesNuGet包,启动时注册编码 provider:Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - 清理密文冗余字符,校验密文合法性
Base64转码前先清理密文字符串中的冗余内容:cipherText = cipherText.Trim().Replace("\r", "").Replace("\n", "").Replace(" ", "");
解密前先验证密文字节数组长度为16的整数倍(AES块大小为128位即16字节),长度不匹配直接判定为密文损坏。 - 使用标准解密流写法,避免自定义截断
public static string Decrypt(byte[] cipherBytes, byte[] key, byte[] iv) { using (var aes = Aes.Create()) { aes.Key = key; aes.IV = iv; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; var decryptor = aes.CreateDecryptor(); using (var ms = new MemoryStream(cipherBytes)) using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) using (var sr = new StreamReader(cs, Encoding.UTF8)) // 编码和加密端对齐 { // 直接读取到流结束,不要自定义缓冲区长度 return sr.ReadToEnd(); } } }
内容的提问来源于stack exchange,提问作者user2295457
相关产品推荐
相关产品推荐

