RCM/RCM/ConfigSerializer.cs

91 lines
3.7 KiB
C#

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace RCM {
public static class ConfigSerializer {
private static readonly string _typeProp = "SerializedType";
public static JObject ObjToJson(object obj) {
JObject json = JObject.FromObject(obj);
json.Add(_typeProp, obj.GetType().FullName);
return json;
}
public static object JsonToObj(JObject json) {
Type type = Type.GetType(json.GetValue(_typeProp).ToString(), true);
json.Remove(_typeProp);
return json.ToObject(type);
}
public static string JsonToString(JToken json) {
var stringWriter = new StringWriter();
var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented };
new JsonSerializer().Serialize(jsonWriter, json);
return stringWriter.ToString();
}
public static JObject StringToJson(string str) {
return JObject.Parse(str);
}
public static string ObjToString(object obj) {
return JsonToString(ObjToJson(obj));
}
public static object StringToObj(string str) {
return JsonToObj(StringToJson(str));
}
public static byte[] Decrypt(byte[] cipherbytes, string password) {
if (string.IsNullOrEmpty(password)) {
return cipherbytes;
}
byte[] salt = new byte[16];
byte[] iv = new byte[16];
Array.Copy(cipherbytes, salt, 16);
Array.Copy(cipherbytes, 16, iv, 0, 16);
using (AesManaged aes = new AesManaged() { KeySize = 128 })
using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt, 16))
using (ICryptoTransform decryptor = aes.CreateDecryptor(pbkdf2.GetBytes(16), iv))
using (MemoryStream memoryStream = new MemoryStream())
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write))
using (BinaryWriter writer = new BinaryWriter(cryptoStream)) {
writer.Write(cipherbytes, 32, cipherbytes.Length - 32);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
}
public static object DecryptObject(byte[] cipherbytes, string password) {
return StringToObj(Encoding.Unicode.GetString(Decrypt(cipherbytes, password)));
}
public static byte[] Encrypt(byte[] plaintext, string password) {
if (string.IsNullOrEmpty(password)) {
return plaintext;
}
using (AesManaged aes = new AesManaged() { KeySize = 128 }) {
aes.GenerateIV();
using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, 16, 16))
using (ICryptoTransform encryptor = aes.CreateEncryptor(pbkdf2.GetBytes(16), aes.IV))
using (MemoryStream memoryStream = new MemoryStream())
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
using (BinaryWriter writer = new BinaryWriter(cryptoStream)) {
writer.Write(plaintext);
cryptoStream.FlushFinalBlock();
return pbkdf2.Salt.Concat(aes.IV).Concat(memoryStream.ToArray()).ToArray();
}
}
}
public static byte[] EncryptObject(object obj, string password) {
return Encrypt(Encoding.Unicode.GetBytes(ObjToString(obj)), password);
}
}
}