Sunday 22 June 2008

Silverlight Encryption (Part 2) - Generating the key

Following on from my previous article, I will now explain some of the techniques used for encryption within Silverlight, specifically focusing on generation of the key used for encryption/decryption.

AES

We will be using the AES algorithm to encrypt/decrypt our data, this is symmetric-key algorithm which means a single key is used to encrypt and decrypt the data.

If your application needs to both encrypt/decrypt data then a symmetric-key algorithm is the correct choice. In Silverlight applications if you are looking to encrypt data to be stored in Isolated Storage then a symmetric-key algorithm is the right choice.

Within Silverlight 2 at this time, AES is the only standard symmetric-key algorithm available (you can of course write your own). AESManaged is available within the System.Security.Cryptography namespace.

Key Storage

To protect our data we need to protect the key. If the key is easily obtained then our data can be easily decrypted.

We should not keep the key within the application as it will be possible for someone to download the application and use reflector to get the key.

Therefore we really have 2 options

1) Generate a key based upon user input

2) Download the key (based on authenticated login) from the backend website/(web service)

If we use download the key from the server, this provides a pretty secure method of encryption. The only downside to this technique, is that it means that the user must have access to the website. So this is perfect for online scenarios, but not great for offline scenarios. So for 99% (figure pulled of the air rather than based up on some statistical survey) of Silverlight applications this is the best technique to use.

Offline Scenarios

If you wish to make your Silverlight application available offline, then you will need to generate your key based on user input (this is because if your application is offline your user won't be able to download the key). You can't even store the key anywhere (as this would defeat the point of encrypting the data in the first place).

In this case it may' be worth using a username/password mechanism for the application and generating your key based upon the username/password.

The downside of this approach is that you will have to keep the username/password mechanism of the application/website and the encryption of the data in sync.

Generation of the Key

The following code is used to generate the key used to perform the encryption/decryption for the AES algorithm.

To generate the key we use Rfc2898DeriveBytes (which is provided in the BCL) to generate hash keys for passwords and supports the use of a salt.

internal static byte[] GetHashKey(string hashKey)
{
// Initialise
UTF8Encoding encoder = new UTF8Encoding();

// Get the salt
string salt = "I am a nice little salt";
byte[] saltBytes = encoder.GetBytes(salt);

// Setup the hasher
Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(hashKey, saltBytes);

// Return the key
return rfc.GetBytes(16);
}

So in our examples we had previously we could generate the keys and store them on the web server and the application could download the key, or you would pass in a username/password into the GetHashKey method which would generate the key for you.

In our final article we will make use of the generated key to perform the encryption.

In the meantime you can download the source from my skydrive

You can also view an online demo of this application here.

No comments: