C# AES加密JSON字符串截断5字符,反序列化遇JsonReaderException
问题分析与解决方案
问题根源
你的代码存在两处核心错误导致解密后JSON字符串截断,进而触发反序列化异常:
- 错误1:错误预设解密数组长度
AES属于块加密算法,密文长度是块大小(默认16字节)的整数倍,因此密文长度会比原始明文长。你直接用encryptedBytes.Length - key.Length - iv.Length作为解密后数组的长度,这个值是密文的长度,而非实际解密后的明文长度,导致数组包含无效填充字节或数据读取不完整。 - 错误2:未正确处理
CryptoStream.Read的返回值cryptoStream.Read仅返回单次调用读取的字节数,单次调用无法保证读取全部解密数据,直接填充到预设数组会导致部分数据丢失,表现为字符串截断。 - 额外语法问题:加密代码块结束后多了一个无关的
{,虽不影响运行逻辑,但会导致代码结构混乱,建议删除。
修复后的完整代码
using System; using System.IO; using System.Security.Cryptography; using System.Text; using Newtonsoft.Json; namespace Test { public class Test { public static void Run() { string encryptedString = ""; // 创建示例JSON对象 var data = new { name = "Alice", age = 30, email = "alice@example.com" }; // 将JSON对象序列化为字节数组 var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)); // 创建AES加密算法实例 using (var aes = Aes.Create()) { // 生成随机加密密钥和IV aes.GenerateKey(); aes.GenerateIV(); // 加密JSON字节数组 byte[] encryptedBytes; using (var encryptor = aes.CreateEncryptor()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(jsonBytes, 0, jsonBytes.Length); cryptoStream.FlushFinalBlock(); encryptedBytes = memoryStream.ToArray(); } // 将加密字节与密钥、IV合并 byte[] combinedBytes = new byte[aes.Key.Length + aes.IV.Length + encryptedBytes.Length]; Console.WriteLine($"{combinedBytes.Length}, {aes.Key.Length} {aes.IV.Length}"); Array.Copy(aes.Key, 0, combinedBytes, 0, aes.Key.Length); Array.Copy(aes.IV, 0, combinedBytes, aes.Key.Length, aes.IV.Length); Array.Copy(encryptedBytes, 0, combinedBytes, aes.Key.Length + aes.IV.Length, encryptedBytes.Length); // 将结果转换为Base64编码字符串 encryptedString = Convert.ToBase64String(combinedBytes); Console.WriteLine(encryptedString); } // 将Base64编码字符串转换为字节数组 var encryptedBytes = Convert.FromBase64String(encryptedString); // 从字节数组中提取密钥和IV var key = new byte[32]; var iv = new byte[16]; Array.Copy(encryptedBytes, 0, key, 0, key.Length); Array.Copy(encryptedBytes, key.Length, iv, 0, iv.Length); // 创建AES加密算法实例并设置密钥和IV using (var aes = Aes.Create()) { aes.Key = key; aes.IV = iv; // 解密数组中剩余的字节 using (var decryptor = aes.CreateDecryptor()) using (var memoryStream = new MemoryStream(encryptedBytes, key.Length + iv.Length, encryptedBytes.Length - key.Length - iv.Length)) using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) using (var outputStream = new MemoryStream()) { // 自动处理所有解密字节,无需预设长度 cryptoStream.CopyTo(outputStream); var decryptedBytes = outputStream.ToArray(); // 将解密后的字节数组转换为字符串并反序列化JSON对象 var jsonString = Encoding.UTF8.GetString(decryptedBytes); System.Console.WriteLine(jsonString); var json = JsonConvert.DeserializeObject(jsonString); Console.WriteLine(json); } } } } }
修复说明
- 使用流接收解密结果:通过
CryptoStream.CopyTo将解密数据完整写入MemoryStream,自动处理所有字节,无需手动猜测解密后长度,避免截断或无效字节。 - 移除冗余代码块:删除加密块结束后多余的
{,规范代码结构。 - 保留正确加密逻辑:原加密部分代码无问题,无需修改。
验证结果
修复后解密得到完整JSON字符串:
{"name":"Alice","age":30,"email":"alice@example.com"}
反序列化过程不会再抛出JsonReaderException异常。
内容的提问来源于stack exchange,提问作者Thomas Caio
相关产品推荐
相关产品推荐

