Extension Me Serialize: With Encryption!

Extension methods provide the wonderful ability to extend the functionality provided by the .NET Framework. This entry uses extension methods to encrypt serialized data. The post assumes the reader knows what serialization is and understands the basics of programming in C#.

Security is a constant concern for those of us handling personal data. Encrypting personal data is a piece of this security by aiding in the protection of our applications’ data and the prevention of identity theft. This post will focus on just one piece of the security puzzle, but there are many other methods of protecting sensitive data including Defense in Depth. I’ll leave the details of Defense in Depth for another time but, generally speaking, this is a concept in which multiple layers of security controls are placed throughout a system. This entry gives a detailed example of one way to implement a security control meant to aid in implementing a Defense in Depth strategy. The reader is strongly recommended to delve deeper into the subjects of security, encryption and Defense in Depth implementations before attempting to go to production with their solution.

Some have told me, “I’m using SSL, I don’t need this!” It is true, SSL (Secure Sockets Layer) is generally known as a highly reliable and trustworthy form of secure communication over the internet. Beyond the holes already found, the issue when solely trusting SSL is that a potential attacker can still view the information sent using this form of communication. Once the information has arrived at its destination it is decrypted to be consumed by the system. At this point, the fact SSL was used to get the information here is irrelevant. Using banking information as example data, if a system sends data to a database through an SSL connection, the transfer is encrypted but, once it gets to the database server, the data is decrypted. This means that at the data level on the database server, the bank information is free for viewing. An attacker would be able to simply look at the bank information if they were to access the database server. If the bank information was encrypted, the attacker could not simply view it, effectively adding protection at the data level. This is a simple example of Defense in Depth, where the transaction is secured (connection encryption), and the storage is secured (data encryption). There will likely be more layers to this spanning from hardware to software including firewalls, intrusion detection systems, various forms of authentication, authorization and other access control methods.

Below is the implementation of the serializer implemented to serialize an encrypted file stream.

public static void SerializeAndEncrypt<T>(this T @this, ICryptoTransform encryptor, String path) where T : ISerializable
{
   //
   // Parameter Validation omitted for brevity ...
   //

 
   using (var stream = new FileStream
   (
      path, FileMode.OpenOrCreate,
      FileSystemRights.CreateFiles | FileSystemRights.Read,
      FileShare.None, 128, FileOptions.None
   ))
   {
      using (var crypto = new CryptoStream(stream, encryptor, CryptoStreamMode
      
.Write))
      {
         BinaryFormatter formatter = new BinaryFormatter();
         formatter.Serialize(crypto, @this);
      }
   }
}

This is very similar to my previous post but with some extra fluff for Encryption. The generic method is constrained to only ISerializable objects to ensure the object intended for serialization is able to be serialized. The execution continues with a FileStream object created using the given path. This FileStream object is then used, along with the given ICryptoTransform parameter, to create a CryptoStream. Then the CryptoStream instance and the extended object are sent to the Serialize method of a new BinaryFormatter. Please see the MSDN documentation on creating cryptographic transforms for more information on ICryptoTransform and CryptoStream.

In regards to coding best practices I stress the validation of parameters. Also, use FxCop or code analysis set to “All Rules” for the projects in your solution to help “force” yourself to do the right thing. Be diligent with your use of these tools. Don’t overuse the warning suppression feature since the tools become less effective the more warnings are suppressed.

If an object is serialized, it will likely be deserialized. The implementation of the deserializer is below. This extension method is used to deserialize and decrypt an encrypted file stream.

public static T DeserializeAndDecrypt<T>(this T @this, ICryptoTransform decryptor, String path) where T : 
ISerializable
{
   //
   // Parameter Validation omitted for brevity ...
   //

 
   using (var stream = new FileStream
   (
      path, FileMode.OpenOrCreate,
      FileSystemRights.CreateFiles | FileSystemRights.Read,
      FileShare.None, 128, FileOptions.None
   ))
   {
      using (var crypto = new CryptoStream(stream, decryptor, CryptoStreamMode
      .Read))
      {
         BinaryFormatter formatter = new BinaryFormatter();
         @this = (T)formatter.Deserialize(crypto);
      }
   }
}

The implementation is much like serialization except for a few minor yet very important changes. The method returns a type of the object being extended and the CryptoStream instance is created in read mode with the given decryptor transform. The Deserializer method of the BinaryFormatter is used to deserialize the CryptoStream instance. The result is cast to (T) and returned.

A particularly useful scenario for employing the extension method is when you want to store serialized data on the file system or a database. Sure, serializing the objects can obscure the data but, as you can see in the image below sensitive information can still be extracted:

Extracted Information

The data is obscured but, it is still not protected at a reasonable level. The excerpt above was taken from the cleansed output of a system accepting customers’ addresses, birthdates, and social security numbers. Pay particularly close attention to:

Extracted Information with Encryption

If this were actual personal information: consider Al & Peggy’s identity stolen! There goes your customer’s full address, birthdate, and social security number. If this was real data, it would be devastating. The ability to grab one customer’s personal information could lead to the ability to grab them all. Al & Peggy can no longer go to the Bahamas, and your company’s reputation is tainted.

If the customers’ data was serialized with encryption, this risk would have been mitigated:

Extracted Information Highlights

Above depicts the use of the serializer with encryption which made everything unreadable to humans. This effectively protected the customer’s data by not allowing a potential attacker to simply read the private information.

This post provides you with a detailed walkthrough of creating extension methods for the encryption and decryption of serialized data for aiding in strategic Defense in Depth implementations. I’d advise the use of encryption when there is a potential for sensitive data to be exposed to any unauthorized personnel. There are tools available to help you determine these areas such as the SDL Thread Modeling Tool. The use of encryption when serializing has numerous positive effects on security that would surely overcome the cost of implementation. Encryption: like it, love it, use it! Though, do not make the mistake of thinking encrypted data alone means secure data. The implementations above are meant to aid in Defense in Depth strategies. Further action must be taken to ensure its effectiveness. The keys used for encryption and decryption must be managed. If an attacker has access to the keys, the encryption is useless. Take Eric Lippert’s advice, keep it secret, keep it safe.

877-277-1044
Categories

Copyright 2013 Magenic, All rights Reserved