Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

TripleDes Encryption with Key and IV for Windows Phone

Given how long TripleDes has been around you would have thought that it would be just part of any decent platform. Not so! Unfortunately Windows Phone support for cryptography in the core apis seems to be quite lacking (although it does now have DPAPI support for protecting local data). There also seems to be a lack of good documentation/examples on how to get existing code bases to work. It turns out that it’s not that hard if you reuse the massive Bouncy Castle cryptography library (http://www.bouncycastle.org/csharp/). Here are the steps to encrypt and decrypt with TripleDes using the Bouncy Castle library for Windows Phone.

The first step is to download the source code from http://www.bouncycastle.org/csharp/. Whilst there are binaries there I didn’t see a set built for Windows Phone.

With the source code downloaded, you’ll need to expand the zip and copy the contents of the \bccrypto-net-1.7-src\csharp\crypto folder into a new Windows Phone Class Library project. You’ll most likely have to exclude the default AssemblyInfo.cs file too in order for it to compile.

Next step is to reference the class library from your application and now you’re good to start using the API.

We’ll start by declaring a very basic UI – in this case made up of an input TextBox for the value to be encrypted, then two output TextBlocks for the encrypted and the subsequent decrypted values. There are two Buttons to instigate the encryption and decryption to make the process easier to follow.

<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <TextBox x:Name="TextToEncrypt"
               Text="Text to encrypt" />
   <Button Content="Encrypt"
            Click="EncryptText" />
   <TextBlock x:Name="TextToDecrypt" />
    <Button Content="Decrypt"
            Click="DecryptText" />
    <TextBlock x:Name="DecryptedText" />
</StackPanel>

To perform the encryption we’re going to need a Key and an Initialization Vector (IV). The following is a randomly created key and doesn’t correlate to any production or test keys that I’m aware of.

private static readonly byte[] Key = new byte[]
                                            {
                                                34, 77, 23, 23, 43, 73, 23, 43,
                                                2, 64, 23, 67, 34, 12, 32, 5,
                                                3, 64, 75, 23, 54, 23, 12, 52
                                            };

private static readonly byte[] IV = new byte[] { 2,45,123,22,66,234,45,34 };

The majority of the work is done in the RunTripleDes method, which takes two parameters: the input value and whether you want it encrypted (true) or decrypted (false). The important thing in this method is to make sure you initiate the Cipher engine with the correct parameters. The following uses the parameters that are consistent with the default TripleDESCryptoServiceProvider that is available to applications written using the full .NET Framework (ie Mode is CBC and Padding is PKCS7). If your encryption needs are different then look through the CipherUtilities class to see what parameters you need to specify in the GetCipher method and then make sure you provide the appropriately structured parameter to the Init method.

public byte[] RunTripleDes(byte[] input, bool encrypt)
{              
        var keyParam = new DesEdeParameters(Key);
        var ivParam = new ParametersWithIV(keyParam, IV);
        var engine = CipherUtilities.GetCipher("DESede/CBC/PKCS7PADDING");
        engine.Init(encrypt, ivParam);
        var output = engine.DoFinal(input);
        return output;
}

To make the code a little easier to follow, we’ll add Encrypt and Decrypt methods to wrap the RunTripleDes method.

public byte[] Encrypt(byte[] input)
{
    return RunTripleDes(input, true);
}
public byte[] Decrypt(byte[] input)
{
    return RunTripleDes(input, false);
}

Lastly, we just need to invoke these methods from the respective button Click event handlers.

private void EncryptText(object sender, RoutedEventArgs e)
{
    var input = Encoding.UTF8.GetBytes(TextToEncrypt.Text);
    var encryptedValue = Encrypt(input);
    TextToDecrypt.Text = Convert.ToBase64String(encryptedValue);
}

private void DecryptText(object sender, RoutedEventArgs e)
{
    var input = Convert.FromBase64String(TextToDecrypt.Text);

    var decryptedValue = Decrypt(input);
    DecryptedText.Text = Encoding.UTF8.GetString(decryptedValue, 0, decryptedValue.Length);
}

You’ll have noticed that we use the UTF8 encoder to convert the input text into a byte array for encryption but that we use the ToBase64String static method on the Convert class to convert the encrypted byte array into text for displaying. We could use the UTF8 encoder to do this but you’d find that when you attempt to convert back to a byte array you may lose bytes. Using ToBase64String and FromBase64String ensures you don’t lose any data in the conversion back and forth from string format – this is particularly important if you’re going to send the encrypted data across the wire (for example a SOAP or REST service)

Ok, let’s give this a whirl – running the application you should be able to enter some text in the TextBox, click the Encrypt button and see the encrypted data, then click the Decrypt button to see the original text appear again (as in the image below).

image

Hope this helps you get started using Bouncy Castle for working with TripleDes in your Windows Phone application.

Loading