You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# .NET AES256解密抛出CryptographicException:无效填充无法移除

解决AES解密“Padding is invalid and cannot be removed”错误

以下是针对你问题的排查方向和解决方法:

1. 确保加密/解密的填充、模式完全一致

AES的PaddingMode和CipherMode必须在加密、解密两端完全匹配,哪怕一端默认值和你手动设置的不同都会出错:

  • 明确指定PaddingMode.PKCS7(.NET默认,但显式设置更稳妥)
  • 明确指定CipherMode.CBC(同样是默认,但避免意外修改)

示例代码里要统一设置:

aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.CBC;

2. 加密时务必完成数据流收尾

如果加密时使用CryptoStream,必须确保所有数据(包括填充块)都写入文件:

  • 不要省略FlushFinalBlock(),或者直接用using块包裹CryptoStream——它的Dispose方法会自动调用FlushFinalBlock(),避免遗漏填充数据。

错误示例(可能丢填充):

// 错误:写完数据直接关闭流,没处理填充
cryptoStream.Write(buffer, 0, bytesRead);
outputStream.Close();

正确做法(用using自动处理):

using (CryptoStream cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
{
    inputStream.CopyTo(cryptoStream);
} // 这里自动调用FlushFinalBlock和Dispose

3. 验证加密文件的完整性

即使你认为密钥/IV一致,也要确认加密后的文件没有被截断或损坏:

  • 对比加密后文件的字节长度和解密时读取的字节数是否一致
  • 对加密文件生成SHA256哈希,解密前先验证哈希,排除文件损坏问题

4. 检查密钥/IV的读取方式

你用openssl rand生成的是二进制密钥,必须直接以字节数组读取,不能经过字符串编码转换(比如UTF8.GetBytes):

  • 读取密钥用File.ReadAllBytes("key.bin"),确保拿到的是原始32字节随机数据
  • 如果加密时把密钥转成字符串再转回字节,会因为二进制数据无法被UTF-8正确编码而丢失信息

5. 避免使用过时的AESManaged类

推荐用Aes.Create()替代AESManaged,前者是.NET官方推荐的实现,更稳定且安全:

using (Aes aes = Aes.Create())
{
    // 配置密钥、IV、模式、填充
}

补充:IV的正确使用方式

每个加密文件都应该使用随机IV(不要固定IV),IV不需要保密,可以直接存储在加密文件的开头(比如前16字节),解密时先读取前16字节作为IV,再读取剩余内容解密,这样既安全又避免IV匹配错误。


内容的提问来源于stack exchange,提问作者erloup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:37:11