解密必然失败,因每次调用CreateEncryptor()和CreateDecryptor()均自动生成新IV,导致CBC模式下IV不匹配而抛Padding异常;IV必须显式获取、传输并精确复用。

直接用 Aes.Create() 加密字符串,不显式管理 IV 和 Key,解密几乎必然失败——不是算法不对,是参数没对齐。
为什么每次调用 CreateEncryptor() 都会解密失败
很多人写成这样:
using var aes = Aes.Create(); var encryptor = aes.CreateEncryptor(); // ❌ 每次都生成新 IV var decryptor = aes.CreateDecryptor(); // ❌ 用的不是同一个 IV
问题在于:CreateEncryptor() 和 CreateDecryptor() 在没传参时,会各自调用 GenerateIV(),导致加解密用的 IV 完全不同。而 AES-CBC 模式下,IV 差一个字节,整个解密就抛 CryptographicException: Padding is invalid。
-
IV必须在加密后显式取出(aes.IV),并和密文一起保存或传输 - 解密时必须用**完全相同的字节数组**作为
IV参数传给CreateDecryptor(IV, Key) - 别依赖
aes.IV在多次调用间“自动保持”,它只在你调用GenerateIV()后才有效,且不会持久化
Key 和 IV 怎么生成才不踩坑
硬编码字符串如 "1234567890123456" 当 Key 或 IV,等于裸奔。
-
IV必须每次加密都重新生成:调用aes.GenerateIV(),长度固定为 16 字节;可明文传输(比如拼在密文前),但绝不能复用 -
Key别用Encoding.UTF8.GetBytes("mykey")—— 长度不可控、熵值低;推荐用Rfc2898DeriveBytes从口令派生,盐值随机、迭代次数 ≥10000 - 设
aes.KeySize = 256后,你给的Key字节数必须正好是 32;给 31 或 33 字节,直接抛CryptographicException: Specified key is not a valid size
Base64 加密结果解不开?先查这三处
常见报错:The input data is not a complete block、Bad Data、Length of the data to decrypt is invalid,基本都不是算法问题,而是序列化/反序列化断点。
- 加密输出的
byte[]是否包含完整IV + 密文?如果只存了密文,解密时就没法还原IV - Base64 解码后字节数组长度是否是 16 的整数倍?如果不是,说明原始密文被截断、拼接错误或编码前漏了
IV - 两端的
CipherMode(默认CBC)、PaddingMode(默认PKCS7)是否一致?Java/Python 对端若用NoPadding或ZeroPadding,必须显式指定
跨平台部署时 Aes.Create() 返回 null 怎么办
在 Unity IL2CPP、.NET Framework 4.5 以下或某些 AOT 环境中,Aes.Create() 可能返回 null,这不是你代码错了,是运行时没加载实现。
- 稳妥写法:
var aes = Aes.Create() ?? new AesManaged(); -
AesManaged是纯托管实现,.NET Core 3.1+ 和 .NET 5+ 仍可用,且跨平台;AesCryptoServiceProvider仅 Windows 可用,Linux/macOS 会抛PlatformNotSupportedException - 无论用哪个,
IV和Key的生成、传递、对齐逻辑完全一样——换实现不等于换规则
最易被忽略的一点:加解密不是“能跑通就行”,而是 IV 和 Key 的字节数组必须逐字节相等;哪怕只差一个字节,也不会乱码,而是直接异常。别靠肉眼比对 Base64,用 Convert.ToHexString() 打印原始字节再确认。


















