2020-02-17
Introducing JsonCryption!
I couldn't find a useful .NET library for easy and robust JSON property-level encryption/decryption, so I made one.
The GitHub page covers more details, but this is the gist:
Installation:
Install-Package JsonCryption.Newtonsoft
// There's also a version for System.Text.Json, but the implementation
// for Newtonsoft.Json is better, owing to the greater feature surface
// and customizability of the latter at this time.
Configuration:
// pseudo code (assuming using Newtonsoft.Json for serialization)
container.Register<JsonSerializer>(() => new JsonSerializer() {
ContractResolver = new JsonCryptionContractResolver(container.Resolve<IDataProtectionProvider>())
});
Usage:
var myFoo = new Foo("some important value", "something very public");
class Foo
{
[Encrypt]
public string EncryptedString { get; }
public string UnencryptedString { get; }
public Foo(string encryptedString, string unencryptedString)
{
...
}
}
var serializer = // resolve JsonSerializer
using var textWriter = ...
serializer.Serialize(textWriter, myFoo);
// pseudo output:
// {
// "encryptedString": "akjdfkldjagkldhtlfkjk...",
// "UnencryptedString": "something very public"
// }
Why I need JsonCryption
Discovery path
First Stop: Newtonsoft.Json.Encryption
Overriding JsonConverter
public class Settings {
[JsonConverter(typeof(EncryptingJsonConverter), "#my*S3cr3t")]
public string Password { get; set; }
}
Initial Attempt for System.Text.Json
public sealed class EncryptAttribute : JsonConverterAttribute
{
public EncryptAttribute() : ElementsBase(typeof(EncryptedJsonConverterFactory))
{
}
}
- Overriding the
JsonConverterAttribute
ultimately required using a Singleton pattern rather than clean Dependency Injection - System.Text.Json currently offers no ability to serialize non-public properties, nor fields of any visibility. For most DDD scenarios, this was also a non-starter.