using System.Collections.Generic;
using System.Security.Cryptography;
using Newtonsoft.Json.Serialization;
public static void Main(string[] args)
UserInfo user = new UserInfo
UserPassword = "Hunter2",
FavoriteColor = "atomic tangerine",
CreditCardNumber = "1234567898765432",
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new EncryptedStringPropertyResolver("My-Sup3r-Secr3t-Key");
Console.WriteLine("----- Serialize -----");
string json = JsonConvert.SerializeObject(user, settings);
Console.WriteLine("----- Deserialize -----");
UserInfo user2 = JsonConvert.DeserializeObject<UserInfo>(json, settings);
Console.WriteLine("UserName: " + user2.UserName);
Console.WriteLine("UserPassword: " + user2.UserPassword);
Console.WriteLine("FavoriteColor: " + user2.FavoriteColor);
Console.WriteLine("CreditCardNumber: " + user2.CreditCardNumber);
Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
public string UserName { get; set; }
public string UserPassword { get; set; }
public string FavoriteColor { get; set; }
public string CreditCardNumber { get; set; }
public class EncryptedStringPropertyResolver : DefaultContractResolver
private byte[] encryptionKeyBytes;
public EncryptedStringPropertyResolver(string encryptionKey)
if (encryptionKey == null)
throw new ArgumentNullException("encryptionKey");
using (SHA256Managed sha = new SHA256Managed())
this.encryptionKeyBytes =
sha.ComputeHash(Encoding.UTF8.GetBytes(encryptionKey));
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
foreach (JsonProperty prop in props.Where(p => p.PropertyType == typeof(string)))
PropertyInfo pi = type.GetProperty(prop.UnderlyingName);
if (pi != null && pi.GetCustomAttribute(typeof(JsonEncryptAttribute), true) != null)
new EncryptedStringValueProvider(pi, encryptionKeyBytes);
class EncryptedStringValueProvider : IValueProvider
PropertyInfo targetProperty;
private byte[] encryptionKey;
public EncryptedStringValueProvider(PropertyInfo targetProperty, byte[] encryptionKey)
this.targetProperty = targetProperty;
this.encryptionKey = encryptionKey;
public object GetValue(object target)
string value = (string)targetProperty.GetValue(target);
byte[] buffer = Encoding.UTF8.GetBytes(value);
using (MemoryStream inputStream = new MemoryStream(buffer, false))
using (MemoryStream outputStream = new MemoryStream())
using (AesManaged aes = new AesManaged { Key = encryptionKey })
outputStream.Write(iv, 0, iv.Length);
ICryptoTransform encryptor = aes.CreateEncryptor(encryptionKey, iv);
using (CryptoStream cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
inputStream.CopyTo(cryptoStream);
return Convert.ToBase64String(outputStream.ToArray());
public void SetValue(object target, object value)
byte[] buffer = Convert.FromBase64String((string)value);
using (MemoryStream inputStream = new MemoryStream(buffer, false))
using (MemoryStream outputStream = new MemoryStream())
using (AesManaged aes = new AesManaged { Key = encryptionKey })
byte[] iv = new byte[16];
int bytesRead = inputStream.Read(iv, 0, 16);
throw new CryptographicException("IV is missing or invalid.");
ICryptoTransform decryptor = aes.CreateDecryptor(encryptionKey, iv);
using (CryptoStream cryptoStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read))
cryptoStream.CopyTo(outputStream);
string decryptedValue = Encoding.UTF8.GetString(outputStream.ToArray());
targetProperty.SetValue(target, decryptedValue);
[AttributeUsage(AttributeTargets.Property)]
public class JsonEncryptAttribute : Attribute