加密解密JSON失败

时间:2017-05-22 14:03:11

标签: c# json encryption

我正在尝试EncryptDecrypt JSON个文件。它几乎可以工作,但是当文件被加密(写入)时,似乎有些东西丢失了。

Length的{​​{1}} 1024 ,但完整档案 1274

所以问题是,它无法成功反序列化。

也许有人有更好的加密解决方案。我觉得我在这里有太多StringReader ..

streams

预期产出

private void _SerializeConfig(string filePath, MyFancyPermissionConfig configuration)
    {
        try
        {
            byte[] fileBytes;

            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (StreamWriter streamWriter = new StreamWriter(memoryStream))
                {
                    JsonSerializer serializer = new JsonSerializer { Formatting = Formatting.Indented };
                    serializer.Serialize(streamWriter, configuration);

                    fileBytes = Encrypt(memoryStream.ToArray());

                    using (FileStream fileStream = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write))
                    {
                        for (int i = 0; i < fileBytes.Length; i++)
                        {
                            fileStream.WriteByte(fileBytes[i]);
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {

        }
    }

    private MyFancyPermissionConfig _DeSerializeConfig(string filePath)
    {
        try
        {
            byte[] fileBytes = Decrypt(File.ReadAllBytes(filePath));
            StringReader stringReader = new StringReader(Encoding.UTF8.GetString(fileBytes));

            JsonSerializer serializer = new JsonSerializer();
            MyFancyPermissionConfig val = (MyFancyPermissionConfig)serializer.Deserialize(stringReader, typeof(MyFancyPermissionConfig));
            return val;

        }
        catch (Exception e)
        {
            return null;
        }
    }

    private static object _EncryptLocker = new object();
    private static object _DecryptLocker = new object();

    static byte[] Key = new byte[] {
         0x43, 0x87, 0x23, 0x72, 0x44, 0x12, 0x85, 0xFA,
         0x43, 0x87, 0x23, 0x72, 0x44, 0x12, 0x85, 0xFA,
         0x43, 0x87, 0x23, 0x72, 0x44, 0x12, 0x85, 0xFA,
         0x43, 0x87, 0x23, 0x72, 0x44, 0x12, 0x85, 0xFA};

    static Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes("SecretKey", new byte[] { 0x43, 0x87, 0x23, 0x72, 0x44, 0x12, 0x85, 0xFA });


    public static byte[] Encrypt(byte[] input)
    {
        lock (_EncryptLocker)
        {
            MemoryStream ms = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = Key;
            aes.IV = pdb.GetBytes(aes.BlockSize / 8);
            CryptoStream cs = new CryptoStream(ms,
              aes.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(input, 0, input.Length);
            cs.Close();

            byte[] secArray = ms.ToArray();

            byte[] retval = new byte[aes.IV.Length + secArray.Length];
            Array.Copy(aes.IV, 0, retval, 0, aes.IV.Length);
            Array.Copy(secArray, 0, retval, aes.IV.Length, secArray.Length);

            return retval;
        }
    }

    public static byte[] Decrypt(byte[] input)
    {
        lock (_DecryptLocker)
        {

            MemoryStream ms = new MemoryStream();
            Aes aes = new AesManaged();

            byte[] IV = input.Take(aes.BlockSize / 8).ToArray();

            byte[] temp = input.Skip(aes.BlockSize / 8).ToArray();

            aes.Key = Key;
            aes.IV = IV;
            CryptoStream cs = new CryptoStream(ms,
              aes.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(temp, 0, temp.Length);
            cs.Close();
            return ms.ToArray();
        }
    }

StringReader的输出

{
  "Users": [
    {
      "Name": "Admin",
      "Password": "00b29c074dc8fadec52828d03586f2700c11eeafdd22a4f095394ee6509226972d3a0e106779f1687325d913f8ca08b2946f017210a4b745c6edfa39d6ee9a51",
      "UserGroup": {
        "Name": "Administrator",
        "Description": "max Userlevel",
        "Permissions": [
          {
            "Name": "UserManagement",
            "Description": "Allows User configurations"
          },
          {
            "Name": "ApplicationShutdown",
            "Description": "Allows User to close the application"
          }
        ]
      },
      "Timeout": "00:10:00"
    }
  ],
  "UserGroups": [
    {
      "Name": "Administrator",
      "Description": "max Userlevel",
      "Permissions": [
        {
          "Name": "UserManagement",
          "Description": "Allows User configurations"
        },
        {
          "Name": "ApplicationShutdown",
          "Description": "Allows User to close the application"
        }
      ]
    }
  ],
  "UserPermissions": [
    {
      "Name": "UserManagement",
      "Description": "Allows User configurations"
    },
    {
      "Name": "ApplicationShutdown",
      "Description": "Allows User to close the application"
    }
  ]
}

2 个答案:

答案 0 :(得分:1)

我不知道为什么你的东西不起作用,但是我使用JsonConvert和更简单的File.WriteAllBytes()函数重写了序列化和反序列化函数,它不再切断任何东西了

private static void _SerializeConfig(string filePath, MyFancyPermissionConfig configuration)
{
    try
    {
        var str = JsonConvert.SerializeObject(configuration, Formatting.Indented);
        var bytes = Encoding.UTF8.GetBytes(str);
        Console.WriteLine("Will serialize string:\n {0}" , str);
        byte[] fileBytes = Encrypt(bytes);
        File.WriteAllBytes(filePath, fileBytes);
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}

private static MyFancyPermissionConfig _DeSerializeConfig(string filePath)
{
    try
    {
        byte[] encryptedBytes = File.ReadAllBytes(filePath);
        byte[] fileBytes = Decrypt(encryptedBytes);
        var str = Encoding.UTF8.GetString(fileBytes);
        Console.WriteLine("Decrypted to: \n" + str);
        return JsonConvert.DeserializeObject<MyFancyPermissionConfig>(str);
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        return null;
    }
}

要进行测试,请创建config.json并调试程序

    public static void Main(string[] args)
    {
        //read a config from file
        byte[] fileBytes = File.ReadAllBytes(@"C:\Users\ABC\Desktop\config.json");
        StringReader stringReader = new StringReader(Encoding.UTF8.GetString(fileBytes));
        JsonSerializer serializer = new JsonSerializer();
        MyFancyPermissionConfig val = (MyFancyPermissionConfig)serializer.Deserialize(stringReader, typeof(MyFancyPermissionConfig));

        //write encrypted config to file
        _SerializeConfig(@"C:\Users\ABC\Desktop\config_enc.json", val);

        //deserialize it again. 
        var des = _DeSerializeConfig(@"C:\Users\ABC\Desktop\config_enc.json");
        Console.ReadLine();
    }

答案 1 :(得分:0)

确保为streamWriter指定UTF8:

using (StreamWriter streamWriter = new StreamWriter(memoryStream, Encoding.UTF8))