Aes.Create() 返回 null 是因未引用 System.Security.Cryptography 或目标框架过低;IV 必须随机生成并随密文保存;CryptographicException: Bad Data 多因密钥/IV 长度错误或数据损坏;大文件应使用 CryptoStream 流式处理。

AES 加密文件时为什么 Aes.Create() 返回 null?
因为没引用 System.Security.Cryptography 命名空间,或者项目目标框架太低(如 .NET Framework 4.6.1 以下或 .NET Core 2.0 以前)。Aes.Create() 在旧版本里是抽象类,不能直接实例化,必须用 Aes.Create("AES") 或改用 AesCryptoServiceProvider(仅 Windows)。
- 推荐统一用
Aes.Create(),它在 .NET Core 2.1+ 和 .NET 5+ 中默认返回安全的实现 - 如果跑在 .NET Framework 4.7.2+,也支持
Aes.Create(),但需确认项目已启用 TLS 1.2+(影响部分加密底层) - 别手动 new
AesManaged——它已被标记为 obsolete,且不支持 AEAD 模式,容易被侧信道攻击
加密文件时 IV 怎么处理才不会解密失败?
IV(初始化向量)不是密码,但必须和密文一起保存,且每次加密都要随机生成。常见错误是硬编码 IV、复用 IV、或把 IV 当作密钥的一部分混用。
- 加密前调用
aes.GenerateIV(),然后把 IV 写入加密文件开头(比如前 16 字节) - 解密时先读取前 16 字节作为 IV,再用剩余数据解密
- IV 不需要保密,但绝不能重复——同一密钥下重复 IV 会导致相同明文生成相同密文,破坏语义安全性
- 别用
DateTime.Now.Ticks或随机数种子生成 IV,必须用密码学安全的随机源(RNGCryptoServiceProvider或RandomNumberGenerator)
怎么避免 CryptographicException: Bad Data?
这个错误九成发生在解密阶段,根本原因是:密钥/IV 长度不对、编码不一致、或数据被截断/损坏。AES 要求密钥长度必须是 128、192 或 256 位(即 16、24、32 字节),IV 固定 128 位(16 字节)。
- 别直接用字符串当密钥——要用
Encoding.UTF8.GetBytes()转字节数组,再用SHA256或Rfc2898DeriveBytes衍生出固定长度密钥 - 文件读写全程用
BinaryReader/BinaryWriter或Stream,别用File.ReadAllText——它会按文本编码解析,破坏二进制密文 - 加密后校验密文长度是否等于原文件长度 + 16(IV)+ 可能的填充字节(PKCS7 默认补满块)
- 调试时可用
Convert.ToBase64String()打印前 32 字节密文和 IV,比对加解密两端是否一致
大文件加密卡死或内存爆掉怎么办?
别一次性把整个文件读进内存再加密。AES 是分块算法,应该用流式处理(CryptoStream),边读边加/解密,内存占用只取决于缓冲区大小。
- 用
FileStream打开源文件,FileStream创建输出文件,中间套一层CryptoStream - 设置缓冲区大小为 8192 或 65536 字节,兼顾性能和内存 —— 太小频繁 IO,太大无意义
- 务必在
using块中释放CryptoStream,否则末尾 PKCS7 填充可能不写入,导致解密报错 - 别在 UI 线程(如 WinForms/WPF)里直接跑大文件加密,会卡界面;改用
Task.Run或BackgroundWorker


















