Leverages the Newtonsoft extension API to encrypt/decrypt specific nodes at serialization time
Clone or download
Latest commit 117cd0f Dec 3, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github GitHubSync update Dec 3, 2018
src . Dec 2, 2018
.editorconfig GitHubSync update Dec 3, 2018
.gitignore add nsb Sep 25, 2017
license.txt . Dec 2, 2018
readme.md Update readme.md Dec 3, 2018

readme.md

Leverages the Newtonsoft extension API to encrypt/decrypt specific nodes at serialization time. So only the notes that require encryption are touched, the remaining content is still human readable. This approach provides an compromise between readability/debugabaility and security.

Already a Patron? skip past this section

Community backed

It is expected that all developers become a Patron to use any of these libraries. Go to licensing FAQ

Platinum Sponsors

Support this project by becoming a Platinum Sponsor. A banner with your company logo will be added here with a link to your website. The banner will also be added to all GitHub repositories under the NServiceBusExtensions organization. A "Sponsored by" text and link will be added the description of the NuGet Package for the life of your sponsorship. You also get 1 hour of remote support per month.

Gold Sponsors

Support this project by becoming a Gold Sponsor. A large company logo will be added here with a link to your website. The logo will also be added to all GitHub repositories under this organization.

Silver Sponsors

Support this project by becoming a Silver Sponsors. A medium company logo will be added here with a link to your website. The logo will also be added to all GitHub repositories under this organization.

Bronze Sponsors

Support this project by becoming a Bronze Sponsors. The company avatar will show up here with a link to your website. The avatar will also be added to all GitHub repositories under this organization.

Patrons

Thanks to all the backing developers! Support this project by becoming a patron.

The NuGet package NuGet Status

https://nuget.org/packages/Newtonsoft.Json.Encryption/

PM> Install-Package Newtonsoft.Json.Encryption

Encryption Algorithms

Any implementation of SymmetricAlgorithm is supported.

Decorating properties

public class ClassToSerialize
{
    [Encrypt]
    public string Property { get; set; }
}

Serialized

{
    "Property":"wSayABpFI3g7a/D6gGTq5g=="
}

Supported property types

  • string
  • byte[]
  • Guid
  • IDictionary<T, string>
  • IDictionary<T, byte[]>
  • IDictionary<T, Guid>
  • IEnumerable<string>
  • IEnumerable<byte[]>
  • IEnumerable<Guid>

Note that only the values in a IDictionary are encrypted.

Usage

The full serialize and deserialization workflow:

// per system (periodically rotated)
var key = Encoding.UTF8.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6");

// per app domain
using (var factory = new EncryptionFactory())
{
    var serializer = new JsonSerializer
    {
        ContractResolver = factory.GetContractResolver()
    };

    // transferred as meta data with the serialized payload
    byte[] initVector;

    string serialized;

    // per serialize session
    using (var algorithm = new RijndaelManaged
    {
        Key = key
    })
    {
        initVector = algorithm.IV;
        using (factory.GetEncryptSession(algorithm))
        {
            var instance = new ClassToSerialize
            {
                Property = "PropertyValue",
            };
            var builder = new StringBuilder();
            using (var writer = new StringWriter(builder))
            {
                serializer.Serialize(writer, instance);
            }
            serialized = builder.ToString();
        }
    }

    // per deserialize session
    using (var algorithm = new RijndaelManaged
    {
        IV = initVector,
        Key = key
    })
    {
        using (factory.GetDecryptSession(algorithm))
        using (var stringReader = new StringReader(serialized))
        using (var jsonReader = new JsonTextReader(stringReader))
        {
            var deserialized = serializer.Deserialize<ClassToSerialize>(jsonReader);
            Console.WriteLine(deserialized.Property);
        }
    }
}

Breakdown

Key

See SymmetricAlgorithm.Key.

Example Key used for RijndaelManaged algorithm in the below sample code:

var key = Encoding.UTF8.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6");

A new valid key can be generated by instanitiating a SymmetricAlgorithm and accessing SymmetricAlgorithm.Key.

EncryptionFactory and JsonSerializer

Generally a single instance of EncryptionFactory will exist per AppDomain.

A single instance of EncryptionFactory is safe to be used for multiple instances of JsonSerializer.

var factory = new EncryptionFactory();

var serializer = new JsonSerializer
{
    ContractResolver = factory.GetContractResolver()
};

Serialization

A single encrypt session is used per serialization instance.

On instantiation the SymmetricAlgorithm will generate a valid IV. This is generally a good value to use for serialization and then stored for deserialization.

string serialized;

// per serialize session
using (var algorithm = new RijndaelManaged
{
    Key = key
})
{
    //TODO: store initVector for use in deserialization
    var initVector = algorithm.IV;
    using (factory.GetEncryptSession(algorithm))
    {
        var instance = new ClassToSerialize
        {
            Property = "PropertyValue",
        };
        var builder = new StringBuilder();
        using (var writer = new StringWriter(builder))
        {
            serializer.Serialize(writer, instance);
        }
        serialized = builder.ToString();
    }
}

Deserialization

A single decrypt session is used per serialization instance.

  • key must be the same as the one use for serialization.
  • initVector must be the same as the one use for serialization. It is safe to be transferred with the serialized text.
using (var algorithm = new RijndaelManaged
{
    IV = initVector,
    Key = key
})
{
    using (factory.GetDecryptSession(algorithm))
    using (var stringReader = new StringReader(serialized))
    using (var jsonReader = new JsonTextReader(stringReader))
    {
        var deserialized = serializer.Deserialize<ClassToSerialize>(jsonReader);
        Console.WriteLine(deserialized.Property);
    }
}

Rebus

The NuGet package NuGet Status

https://nuget.org/packages/Rebus.Newtonsoft.Encryption/

PM> Install-Package Rebus.Newtonsoft.Encryption

Usage

var activator = new BuiltinHandlerActivator();

activator.Register(() => new Handler());
var configurer = Configure.With(activator);

var encryptionFactory = new EncryptionFactory();
var settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All,
    ContractResolver = encryptionFactory.GetContractResolver()
};
configurer.Serialization(s => { s.UseNewtonsoftJson(settings); });
configurer.EnableJsonEncryption(
    encryptionFactory: encryptionFactory,
    encryptStateBuilder: () =>
        (
        algorithm: new RijndaelManaged
        {
            Key = key
        },
        keyId: "1"
        ),
    decryptStateBuilder: (keyId, initVector) =>
        new RijndaelManaged
        {
            Key = key,
            IV = initVector
        });

NServiceBus

The NuGet package NuGet Status

https://nuget.org/packages/NServiceBus.Newtonsoft.Encryption/

PM> Install-Package NServiceBus.Newtonsoft.Encryption

Usage

var configuration = new EndpointConfiguration("NServiceBusSample");
var serialization = configuration.UseSerialization<NewtonsoftSerializer>();
var encryptionFactory = new EncryptionFactory();
serialization.Settings(
    new JsonSerializerSettings
    {
        ContractResolver = encryptionFactory.GetContractResolver()
    });

configuration.EnableJsonEncryption(
    encryptionFactory: encryptionFactory,
    encryptStateBuilder: () =>
        (
        algorithm: new RijndaelManaged
        {
            Key = key
        },
        keyId: "1"
        ),
    decryptStateBuilder: (keyId, initVector) =>
        new RijndaelManaged
        {
            Key = key,
            IV = initVector
        });

Icon

Lock designed by Mourad Mokrane from The Noun Project

Lock by from the Noun Project