Newtonsoft.Json encryption

Component: Newtonsoft Encryption
NuGet Package NServiceBus.Newtonsoft.Encryption (1.x)
This is a community maintained project
Target NServiceBus Version: 7.x

This sample demonstrates how to use the NServiceBus.Newtonsoft.Encryption package to encrypt and decrypt specific properties of a message as it passes through the pipeline. This method of encryption uses extension points in Json.NET and requires less memory and CPU processing than message property encryption.

Running the solution starts two console applications. Endpoint1 encrypts a message and sends it and Endpoint2 receives the encrypted message and decrypts it.

Endpoint1 output

MessageWithSecretData sent.

Endpoint2 output

I know the secret - it's 'betcha can't guess my secret'
SubSecret: My sub secret
CreditCard: 312312312312312 is valid to 3/11/2015 5:21:59 AM
CreditCard: 543645546546456 is valid to 3/11/2016 5:21:59 AM

Code walk-through

Message contract

The Shared project contains MessageWithSecretData.cs, which defines the message contract:

public class MessageWithSecretData :
    IMessage
{
    [Encrypt]
    public string Secret;
    public MySecretSubProperty SubProperty;
    public List<CreditCardDetails> CreditCards;
}

public class MySecretSubProperty
{
    [Encrypt]
    public string Secret;
}

public class CreditCardDetails
{
    public DateTime ValidTo;
    [Encrypt]
    public string Number;
}

Encryption configuration

Encryption is enabled by calling an extension method in Program.cs in both Endpoint1 and Endpoint2:

endpointConfiguration.ConfigurationEncryption();

The extension method is in Shared/EncryptionExtensions.cs:

public static void ConfigurationEncryption(this EndpointConfiguration endpointConfiguration)
{
    var key = Encoding.UTF8.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6");
    var serialization = endpointConfiguration.UseSerialization<NewtonsoftSerializer>();
    var encryptionFactory = new EncryptionFactory();
    serialization.Settings(
        new JsonSerializerSettings
        {
            ContractResolver = encryptionFactory.GetContractResolver()
        });

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

The message on the wire

The serialized message content can be seen by running Endpoint1 without running Endpoint2.

Messages are queued in the .learningtransport folder next to the solution. The message will be contained in a file in the Samples.Encryption.Endpoint2 sub-folder with the following content:

{
   "Secret":"L6sv2UjRckKcO5sYgeLTtOZSM9XEVzjKMgL8HkAqp4s=",
   "SubProperty":{
      "Secret":"QyQCkTOYtpFYVOo7XH8cEw=="
   },
   "CreditCards":[
      {
         "ValidTo":"2018-09-27T13:23:40.0659704Z",
         "Number":"Ne3i4KW+1o99XqowLpy8fw=="
      },
      {
         "ValidTo":"2019-09-27T13:23:40.0659704Z",
         "Number":"GBHwR51fV/56ez2b9ZRfwg=="
      }
   ]
}

Last modified