C#向AES加密文本文件追加字符串后解密出现开头多余字符问题
问题根因
- 你每次调用加密方法追加内容时,都会生成新的随机IV,写入当前文件追加位置的开头,再写入对应加密内容。但解密方法只会读取整个文件最开头的第一个IV,用这个IV解密全文件内容,后面追加的加密片段用了错误的IV解密,自然会出现乱码。
- AES默认开启PKCS7填充,每段独立加密的内容末尾都会自动写入填充字节,多段加密内容拼接后解密时,前一段的填充字节会被当成密文解密,也会产生无效字符。
- 代码中直接手动调用
Close释放资源,若执行过程中抛出异常会导致资源泄漏,建议改用using语句自动释放。
修复方案
方案1:全量加密(最稳定,适配绝大多数场景)
放弃追加模式,每次新增内容时先解密全文件得到所有明文,追加新内容后重新生成IV、全量加密写入文件,解密逻辑无需修改。
示例加密逻辑调整如下:
async void Encrypt() { // 先读取原有明文 List<string> oldContent = await Decrypt() ?? new List<string>(); // 拼接新内容 List<string> newContent = oldContent.Concat(new List<string> { $"RideTitle: {_trakingStartDateTime + _trakingEndDateTime}", "UserNote: -", $"MaxSpeed: {MaxSpeed}", $"AvgSpeed: {AvgSpeed}", $"TotalDistance: {TotalDistance}", $"Steps: {TotalSteps}", $"TotalTime: {_timeElaspsedString_TwentyFourHr}", $"SpeedPoints: {string.Join(',', SpeedPointList)}", $"TimeStampPoints: {string.Join(',', timestampListStings)}", $"LocationPoints: {string.Join(',', LocationListForFiles.Select(p => $"{p.Latitude}_{p.Longitude}"))}" }).ToList(); // 全量加密写入 using FileStream fileStream = new(FilePath, FileMode.Create); using Aes aes = Aes.Create(); byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }; aes.Key = key; byte[] iv = aes.IV; fileStream.Write(iv, 0, iv.Length); using CryptoStream cryptoStream = new(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write); using StreamWriter encryptWriter = new(cryptoStream); encryptWriter.Write(string.Join('\n', newContent)); }
方案2:保留追加模式,适配多段加密
如果文件很大,全量解密加密的IO开销不可接受,可以修改逻辑支持分段解密:
- 每次追加加密时,除了写入IV,还要写入当前段密文的长度
- 解密时循环读取每一段的长度、IV、密文,逐段解密后拼接明文
内容的提问来源于stack exchange,提问作者Hrishikesh Garud
相关产品推荐
相关产品推荐

