[AttributeUsage(AttributeTargets.Property)]
public class JsonEncryptAttribute : Attribute
{
}
public class EncryptedStringPropertyResolver : DefaultJsonTypeInfoResolver
{
private readonly byte[] _encKey;
private readonly byte[] _encIV;
public EncryptedStringPropertyResolver(byte[] encKey, byte[] encIV)
{
_encKey = encKey;
_encIV = encIV;
}
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
JsonTypeInfo typeInfo = base.GetTypeInfo(type, options);
if (typeInfo.Kind != JsonTypeInfoKind.Object) return typeInfo;
foreach (JsonPropertyInfo propertyInfo in typeInfo.Properties)
{
if (propertyInfo.AttributeProvider is { } provider &&
provider.IsDefined(typeof(JsonEncryptAttribute), inherit: true))
{
// serialization
propertyInfo.Get = obj =>
{
PropertyInfo property = typeInfo.Type.GetProperty(propertyInfo.Name); // linking JsonProperty with Property, in order to access the field
return property == null ? null : Encryption.Encrypt(property.GetValue(obj).ToString(), _encKey, _encIV);
};
// deserialization
propertyInfo.Set = (_, val) =>
Encryption.Decrypt(val.ToString(), _encKey, _encIV);
}
}
return typeInfo;
}
}