An issue that frequently causes confusion for MSMQ users is that of message encryption. A message is marked for encryption and sent off, but when it shows up in the destination queue the contents are plainly viewable in clear text. What’s going on here?
Let’s look first at what MSMQ encryption actually does. MSMQ messages can be encrypted by setting the Message.UseEncryption property if using System.Messaging, or PROPID_M_PRIV_LEVEL message property if using the native API. When this property is set, the message body is encrypted using a key from the directory service when it is removed from the outgoing queue to be transmitted on the network. At the destination machine, the message is decrypted and placed in the destination queue. This type of encryption is a part of transport security — if the message were to be intercepted in transport, the contents would be safe.
“But this isn’t what I wanted! I can’t have sensitive customer data sitting in the queue until my application retrieves the message.” This is a common problem, which in the past was often solved by developers adding their own level of encryption to the data before placing it in the message body, and decrypting it after retrieving the message at the destination. This is certainly doable, as the CryptoAPI and its .NET namespace System.Security.Cryptography offer plenty of encryption tools. But it’s a hassle, and can take as much time and code as sending the message itself.
Enter WCF and the NetMsmqBinding. Queued messages sent using this WCF binding can be set to use the Message security mode, which uses the WS-* security protocols to secure the message layer itself. Messages secured in this way will remain encrypted until the WCF client removes the message from the destination queue. The WCF binding can also be set to Transport mode, which allows MSMQ to handle the encryption and authentication on the transport layer, or to Both, which makes everybody happy.
For more information, check out WCF Distributed Application Security.