Rhino Service BusField Level Security
One of the requirements that came up on my current project was the need to secure specific fields in a message during transit. I thought about it a while before I decided that this is something that should be made explicit in the message contract.
Here is an example from the tests:
1: public class ClassWithSecretField2: {3: public WireEcryptedString ShouldBeEncrypted4: {5: get; set;6: }7: }
WireEncryptedString is a type that would be encrypted on the wire, as the name suggest.
And defining the keys in the configuration is done in this way:
1: <facility id="rhino.esb" >2: <bus threadCount="1"3: numberOfRetries="5"4: endpoint="msmq://localhost/test_queue2"5: />6: <messages>7: <add name="Rhino.ServiceBus.Tests"8: endpoint="msmq://localhost/test_queue"/>9: <add name="Rhino.ServiceBus.Tests"10: endpoint="msmq://localhost/test_queue2"/>11: </messages>12: <security>13: <key>f/gdDWbDqHRvpqdRbTs3mxhGdZh9qCaDrasxJGXl+5s=</key>14: </security>15: </facility>
On the wire, it has the following format:
1: <?xml version='1.0' encoding='utf-8'?>2: <esb:messages3: xmlns:esb='http://servicebus.hibernatingrhinos.com/2008/12/20/esb'4: xmlns:tests.classwithsecretfield='Rhino.ServiceBus.Tests.When_Security_Is_Specified_In_Config+ClassWithSecretField, Rhino.ServiceBus.Tests'5: xmlns:datastructures.wireecryptedstring='Rhino.ServiceBus.DataStructures.WireEcryptedString, Rhino.ServiceBus' xmlns:string='string'>6: <tests.classwithsecretfield:ClassWithSecretField>7: <datastructures.wireecryptedstring:ShouldBeEncrypted>8: <string:Value iv='0yL9+t0uyDy9NeP7CU1Wow=='>q9a10IFuRxrzFoZewfdOyg==</string:Value>9: </datastructures.wireecryptedstring:ShouldBeEncrypted>10: </tests.classwithsecretfield:ClassWithSecretField>11: </esb:messages>
Following the Rhino Service Bus philosophy, it is quite a neat solution.
The actual encryption is doing using 256 bits key with Rijndael (AES). I considered other approaches, but all of them had quite a big overhead from manageability perspective.
There are some interesting implications for the implementation, that deserve some discussion. Let us assume that you send such a message to another end point.
If the endpoint…
- has the same key as us, the message will be decrypted and everything works.
- doesn’t have any security defined. At that point, the message will successfully deserialize. Any WireEncryptedString field will contain the encrypted value.
- has a different key defined. Message serialization will fail.
Trying to send a message that contains WireEncryptedString will throw, we do not allow such an action.
And now you can tell me how many holes there are in my system :-)
More posts in "Rhino Service Bus" series:
- (08 Aug 2009) DHT Saga Sate Persisters Options
- (21 Jan 2009) Concurrency Violations are Business Logic
- (19 Jan 2009) Concurrency in a distributed world
- (16 Jan 2009) Saga and State
- (15 Jan 2009) Field Level Security
- (14 Jan 2009) Understanding a Distributed System
- (14 Jan 2009) The Starbucks example
- (14 Jan 2009) Locality and Independence
- (14 Jan 2009) Managing Timeouts

Comments
Comment preview