使用AesCryptoServiceProvider加密解密大文件时出现填充无效异常
问题分析与修复方案
核心问题
你的代码在处理4GB大文件时抛出Padding is invalid and cannot be removed异常,根源在于加密、解密阶段都错误地写入了固定长度的缓冲区数据,而非实际读取到的字节数,导致加密后的文件混入无效残留数据,解密时无法通过PKCS7填充验证。
具体错误点
- 加密方法的写入错误:循环中每次读取到
bytesRead字节后,调用cs.Write(buffer, 0, chunksToRead),但chunksToRead是预设的块大小,最后一次读取大概率不足该值,此时会把缓冲区中之前的残留数据写入加密流,破坏加密文件的完整性。 - 解密方法的写入错误:同样的逻辑问题,读取到
bytesRead字节后,却写入bytesToRead长度的数据,导致解密时处理了多余的无效数据,触发填充验证失败。 - Key处理不一致:加密方法直接使用传入的
key,解密方法却强制复制32字节生成aesKey,若原key长度非32字节,会导致加解密密钥不一致,也可能引发异常。
修复后的代码
加密方法
public static void Encrypt(FileStream fileWriteStream, FileStream fileReadStream, byte[] key, byte[] iv) { const int megabyte = 1024 * 1024; using var aes = Aes.Create(); aes.Key = key; aes.IV = iv; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using var encrypt = aes.CreateEncryptor(); using var cs = new CryptoStream(fileWriteStream, encrypt, CryptoStreamMode.Write); fileReadStream.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[megabyte]; int bytesRead; while ((bytesRead = fileReadStream.Read(buffer, 0, buffer.Length)) > 0) { cs.Write(buffer, 0, bytesRead); // 仅写入实际读取到的有效字节 } cs.FlushFinalBlock(); }
解密方法
public static void DecryptToBytes(Stream cipherBytes, FileStream outputStream, byte[] key, byte[] iv) { const int megabyte = 1024 * 1024; using var encryptor = Aes.Create(); encryptor.Padding = PaddingMode.PKCS7; encryptor.Mode = CipherMode.CBC; encryptor.IV = iv; encryptor.Key = key; // 保持与加密一致的密钥处理逻辑 using var aesDecryptor = encryptor.CreateDecryptor(); using var cryptoStream = new CryptoStream(outputStream, aesDecryptor, CryptoStreamMode.Write); cipherBytes.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[megabyte]; int bytesRead; while ((bytesRead = cipherBytes.Read(buffer, 0, buffer.Length)) > 0) { cryptoStream.Write(buffer, 0, bytesRead); // 仅写入实际读取到的有效字节 } cryptoStream.FlushFinalBlock(); }
关键优化说明
- 简化循环逻辑,移除冗余的长度计算变量,直接用缓冲区长度作为每次读取的最大值,避免块大小计算错误。
- 严格以实际读取的
bytesRead值写入加密/解密流,确保只处理有效数据。 - 统一加解密的密钥处理逻辑,避免密钥不一致问题。
- 使用
using var语法(C# 8.0+)简化资源管理,确保所有流和加密对象自动正确释放。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

