268 Comments

In some cases you may want to tighten up your NServiceBus security by encrypting some parts of your message. This may be required if your client application sends some sensitive data to the server. By following this tutorial you learn how to use the built-in encryption features of the NServiceBus.

We’re not going to build everything from the scratch. Instead, we’re using our previous ASP.NET MVC application as the starting point.

1. Modifying the message

We start by modifying our HelloWorldMessage. Until this point, the message hasn’t contained any data so let’s change this now. NServiceBus contains a class called “WireEncryptedString” which we can use when transporting sensitive string-based data from our client to server. Using the class is as easy as using a regular string. Modify our message class by adding a new member to it:

   1: public class HelloWorldMessage : IMessage
   2: {
   3:     public WireEncryptedString SecretMessage;
   4: }

 

That’s all we have to change in our message so it’s time to modify our client.

2. Modifying the client

As you remember, we create our message in the HomeController. Open it up and modify the SendHello-method so that our new SecretMessage-field is filled with information:

   1: public ActionResult SendHello()
   2: {
   3:     var message = new HelloWorldMessage() { SecretMessage = "Encrypt this" };
   4:
   5:     MvcApplication.Bus.Send(message);
   6:
   7:     return View("Index");

Now open up the client’s web.config and add a new configSection:

<section name="RijndaelEncryptionServiceConfig" type="NServiceBus.Config.RijndaelEncryptionServiceConfig, NServiceBus.Core"/>

And then add the actual configuration just before the </configuration> tag:

<RijndaelEncryptionServiceConfig Key="gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e7"/>
Only one thing left in our client. You must change the NServiceBus initialization so that the RijndaelEncryptionService is used.  After the change, the full configuration in Global.asax.cs looks like this:
   1: Bus = Configure.WithWeb()
   2:     .Log4Net()
   3:     .DefaultBuilder()
   4:     .XmlSerializer()
   5:     .RijndaelEncryptionService()
   6:     .MsmqTransport()
   7:         .IsTransactional(false)
   8:         .PurgeOnStartup(false)
   9:     .UnicastBus()
  10:         //.ImpersonateSender(false)
  11:     .CreateBus()
  12:     .Start();

Before we modify our server, start up the client and hit the “Send hello” few times. Now, fire up the MSMQ monitoring tool of which we learned last time and browse to the Message Queuing – Private Queues – inputqueue – Queue messages. Here you can see listed all the messages in our queue. Double click on one of them and a window with information about your message opens. Select the Body-tab and see what your HelloWorldMessage looks like:

encrypted

As you can see, our SecretMessage has been encrypted. For comparison, here’s a screenshot of the SecretMessage if we were using a regular string:

plain

The last thing to do is to modify our server so that it can read our encrypted message. Let’s do that next.

4. Modifying the server

Our server’s message handler, initialization and configuration must be changed so that it can process the secret message. In message handler, start by modifying our current implementation so that it prints out the secret message to the console:

   1: public void Handle(HelloWorldMessage message)
   2: {
   3:
   4:     Console.WriteLine("Hello world from the client!");
   5:
   6:     var principal = System.Threading.Thread.CurrentPrincipal;
   7:
   8:     var userName = principal.Identity.Name;
   9:     Console.WriteLine("User: {0}", userName);
  10:     Console.WriteLine("Secret message: {0}", message.SecretMessage.Value);
  11: }
Notice the Value-property of the SecretMessage-field.

Now start your server and see how it processes the messages:

encrypted2

As you can see, the encrypted message isn’t yet readable. Open up the Class1, which contains our server initialization. We need to tell our server to use the encryptions by calling the Configure.Instance.RijndaelEncryptionService-method. But, because of some unknown reason, if we just add that one line into our Init-method, the server will crash in startup because of an “Object reference not set”. So instead, modify the Class1-class to look like this snippet:

   1: public class EndpointConfig : IConfigureThisEndpoint, AsA_Server { }
   2: public class ServerInit : IWantCustomInitialization, IWantCustomLogging
   3: {
   4:     public void Init()
   5:     {
   6:         Configure.Instance.RijndaelEncryptionService();
   7:         NServiceBus.SetLoggingLibrary.Log4Net(log4net.Config.XmlConfigurator.Configure);
   8:     }
   9: }

Now we have taken care of our server’s initialization so there’s only one last step left: modifying the server configuration. We need to add the exact same configurations as we did when modifying the web.config. Go ahead and copy-paste the RijndaelEncryptionServiceConfig-configurations from the client and you’re all set.  It’s time to start your application and see the difference.

decrypted

Excellent!

Conclusion

When sending sensitive information between your client and server, it may be best to encrypt some parts of the message. NServiceBus contains a built-in “WireEncryptedString”- and “RijndaelEncryptionService”-classes which make the process very simple.