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

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);
                }
            }
        }
    }
}

修复说明

  1. 使用流接收解密结果:通过CryptoStream.CopyTo将解密数据完整写入MemoryStream,自动处理所有字节,无需手动猜测解密后长度,避免截断或无效字节。
  2. 移除冗余代码块:删除加密块结束后多余的{,规范代码结构。
  3. 保留正确加密逻辑:原加密部分代码无问题,无需修改。

验证结果

修复后解密得到完整JSON字符串:

{"name":"Alice","age":30,"email":"alice@example.com"}

反序列化过程不会再抛出JsonReaderException异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:47:07