.NET Core 2.0中AES+PKCS#7填充报无效填充模式异常求助
问题分析与解决方案
嘿,我仔细看了你的代码,发现核心问题出在十六进制字符串转字节数组的错误方式上,这直接导致密钥、IV和密文的原始字节被篡改,进而触发了填充验证失败的异常。
错误根源
你写的HexStringToString方法把十六进制每两位转成一个字符,再用Encoding.ASCII.GetBytes把字符串转成字节数组——这完全搞错了方向!原因很简单:
- 很多十六进制对应的字节值并不是可打印的ASCII字符,转成char再用ASCII编码时,会把那些非标准ASCII字符(比如0x00-0x1F、0x7F及以上)转换成0x3F(问号),直接破坏了原始的字节信息。
- 正确的做法应该是直接把十六进制字符串转换为字节数组,不需要经过ASCII字符串中转这一步。
修正后的代码
我把你的转换逻辑改对了,同时简化了一些不必要的步骤:
static void Main(string[] args) { string encryptedStr = "e469acd421dd71ade4937736c06fdc9d"; string passphraseStr = "1e089e3c5323ad80a90767bdd5907297b4138163f027097fd3bdbeab528d2d68"; string ivStr = "07dfd3f0b90e25e83fd05ba338d0be68"; // 直接将十六进制字符串转换为字节数组(这才是正确的打开方式) byte[] encryptedBytes = HexStringToBytes(encryptedStr); byte[] key = HexStringToBytes(passphraseStr); byte[] iv = HexStringToBytes(ivStr); // 配置AES解密器 SymmetricAlgorithm algorithm = Aes.Create(); algorithm.Mode = CipherMode.CBC; algorithm.Padding = PaddingMode.PKCS7; algorithm.KeySize = 256; algorithm.Key = key; algorithm.IV = iv; Console.WriteLine("IV length " + iv.Length); // 16,符合AES块大小要求 Console.WriteLine("Key length " + key.Length); // 32,符合256位密钥长度 // 因为已经在algorithm实例上设置了Key和IV,直接调用无参的CreateDecryptor即可 ICryptoTransform transform = algorithm.CreateDecryptor(); // 执行解密 byte[] outputBuffer = transform.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length); // 转成字符串输出 string result = Encoding.ASCII.GetString(outputBuffer); Console.WriteLine(result); // 会输出 Hello world,后面跟着5个\x05的PKCS#7填充字节 Console.ReadLine(); } // 正确的十六进制字符串转字节数组方法 public static byte[] HexStringToBytes(string hexString) { int byteCount = hexString.Length / 2; byte[] bytes = new byte[byteCount]; for (int i = 0; i < byteCount; i++) { bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } return bytes; }
额外答疑
你之前疑惑的“为什么有些解决方案里解密时还要在CreateDecryptor里传Key和IV”:其实两种方式都可行——如果你已经在SymmetricAlgorithm实例上设置了Key和IV,调用无参的CreateDecryptor()就足够了;传参的版本只是给那些不想修改实例属性的场景用的,本质上没有区别。
内容的提问来源于stack exchange,提问作者Flo
相关产品推荐
相关产品推荐

