RSS
 

Don’t forget to Encrypt your Windows Phone 7 Data

02 Jul

Whether you’re targeting Mobile Line of Business apps for the Enterprise or B2C apps for consumers, ensuring that sensitive data is encrypted is a must.  These days, I can’t have a serious discussion with a CIO unless I can assure her that my mobile device can protect data-in-transit and data-at-rest.  You already know that Windows Phone 7 secures data-in-transit via SSL whether you’re using Internet Explorer or calling a Web Service from a Silverlight app.  What you may not know is how it covers the other bases.  A quick look over at http://msdn.microsoft.com/en-us/library/ff402533(v=VS.92).aspx lists the following cryptographic algorithms supported by Windows Phone OS 7.0:

  • AES
  • HMACSHA1
  • HMACSHA256
  • Rfc2898DeriveBytes
  • SHA1
  • SHA256

I thought I’d take some of these algorithms for a spin by building a sample app using Microsoft Visual Studio 2010 Express for Windows Phone.  All I really wanted to do is use AES to encrypt and decrypt some data so I could save it to Isolated Storage.  Doing this would definitely check some of my security checkboxes and those of Microsoft’s customers.

Below are screenshots of the simple app I created.  A TextBox is used to enter the data to be encrypted by AES.  Below that, a PasswordBox control is used to enter a password that works in conjunction with Rfc2898DeriveBytes and HMACSHA1 + a salt value to create a key.  Tapping the Encrypt button calls the Encrypt() method which performs the AES 256 magic and displays the resulting Base64 encrypted data in the Encrypted data TextBox.  Tapping the Decrypt button does the reverse by calling the Decrypt() method to unscramble the data and display the resulting data in the Decrypted data TextBox.

ContosoEncryption1 thumb1 Don’t forget to Encrypt your Windows Phone 7 Data ContosoEncryption2 thumb1 Don’t forget to Encrypt your Windows Phone 7 Data

I also threw some buttons on there to save the newly encrypted data to Isolated Storage as an ApplicationSetting.  As shown in the screenshot on the right, clicking the Retrieve button pulls the encrypted data from Isolated Storage and displays it in a MessageBox.  Keep in mind that you can save this encrypted data to Isolated Storage many different ways including saving it as a file or as part of an XML serialization of a collection of objects.

So let’s take a look at some code. 

The Encrypt() method below takes the data you want to encrypt as well as a password and salt value as arguments.  It uses the AesManaged object with the default values of a 256-bit key and 128-bit block size.  With the help of your supplied password, the encryption key is created using the Rfc2898DeriveBytes object with a dash of salt.  Finally, the MemoryStream and CryptoStream objects work with the AesManaged object to convert your supplied data into an encrypted array of Bytes.  I convert that array into a Base64 string that you can display on the screen, cache in memory, send to a WCF service or save to Isolated Storage.

public string Encrypt(string dataToEncrypt, string password, string salt)
{
    AesManaged aes = null;
    MemoryStream memoryStream = null;
    CryptoStream cryptoStream = null;

    try
    {
        //Generate a Key based on a Password, Salt and HMACSHA1 pseudo-random number generator
        Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));

        //Create AES algorithm with 256 bit key and 128-bit block size
        aes = new AesManaged();
        aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
        aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);

        //Create Memory and Crypto Streams
        memoryStream = new MemoryStream();
        cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write);

        //Encrypt Data
        byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt);
        cryptoStream.Write(data, 0, data.Length);
        cryptoStream.FlushFinalBlock();

        //Return Base 64 String
        return Convert.ToBase64String(memoryStream.ToArray());
    }
    finally
    {
        if (cryptoStream != null)
            cryptoStream.Close();

        if (memoryStream != null)
            memoryStream.Close();

        if (aes != null)
            aes.Clear();
    }
}

 

As you can see below, the Decrypt() method looks remarkably similar to the Encrypt() method except that it does just the opposite.  It accepts your AES-encrypted Base64 data plus a password and salt value as parameters to the method.  The big difference is in the CryptoStream where you have the AesManaged object call CreateDecryptor() instead of CreateEncryptor().  This does the trick and then I convert the unencrypted Byte array into a string.

public string Decrypt(string dataToDecrypt, string password, string salt)
{
    AesManaged aes = null;
    MemoryStream memoryStream = null;
    CryptoStream cryptoStream = null;

    try
    {
        //Generate a Key based on a Password, Salt and HMACSHA1 pseudo-random number generator
        Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));

        //Create AES algorithm with 256 bit key and 128-bit block size
        aes = new AesManaged();
        aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
        aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);

        //Create Memory and Crypto Streams
        memoryStream = new MemoryStream();
        cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write);

        //Decrypt Data
        byte[] data = Convert.FromBase64String(dataToDecrypt);
        cryptoStream.Write(data, 0, data.Length);
        cryptoStream.FlushFinalBlock();

        //Return Decrypted String
        byte[] decryptBytes = memoryStream.ToArray();
        return Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
    }
    finally
    {
        if (cryptoStream != null)
            cryptoStream.Close();

        if (memoryStream != null)
            memoryStream.Close();

        if (aes != null)
            aes.Clear();
    }
}

 

Please keep a few things in mind when encrypting data on the Windows Phone 7 platform.  The OS doesn’t include framework support for storing your passwords and salt values securely nor does it come with any kind of built-in key management.  This means the only way to ensure your encrypted data is actually secure is to make sure your password, salt values and keys are not stored on the phone.  As shown in my example, I require you to enter a password and a salt value each time you want to encrypt or decrypt data. I do not attempt to save those cleartext values anywhere in the system because there is no secure way to store them.  One other thing to think about is that the cleartext password and salt value you entered on the screen can remain in memory at least until the next garbage collection.

Beyond the two Crypto methods above, I created a pair of methods to save and load your encrypted ApplicationSettings to Isolated Storage as shown below:

public void SaveState(string Name, string Value)
{
    if (IsolatedStorageSettings.ApplicationSettings.Contains(Name))
    {
        IsolatedStorageSettings.ApplicationSettings[Name] = Value;
    }
    else
    {
        IsolatedStorageSettings.ApplicationSettings.Add(Name, Value);
    }
}

public string LoadState(string Name)
{
    if (IsolatedStorageSettings.ApplicationSettings.Contains(Name))
    {
        return IsolatedStorageSettings.ApplicationSettings[Name].ToString();
    }
    else
    {
        return "null";
    }
}

 

As you can see from the code samples above, encrypting the sensitive data you use in your Windows Phone 7 apps is completely within your reach.  When you combine this with the following security elements:

  • Apps are tested, digitally signed and securely delivered via the Windows Phone Marketplace
  • No side-loading of potentially insecure apps
  • SSL for data in transit
  • Managed apps run inside secure sandbox
  • Apps have private, inaccessible Isolated Storage
  • Exchange Policies including PIN lock enforcement + Remote wipe

 

It’s clear that Windows Phone 7 has an excellent app security story that’s not only good for consumers, but also means that this mobile app platform is prime-time ready for the Secure Enterprise.

Keep coding,

Rob

 

Tags: , , , , , , , , , , , , , , , , , , ,

Leave a Reply

 

Spam Protection by WP-SpamFree

 
  1. DaveShaw

    July 2, 2010 at 8:38 am

    Are there plans to let the OS manage Encryption Keys like in Windows?

     
  2. Windows Phone 7 Data Encryption | MobileTechWorld

    July 3, 2010 at 2:03 pm

    [...] Rob Tiffany [...]

     
  3. Windows Phone 7 Also Comes With Encryption Methods; Good News for Business Users | GSM Dome - Mobile Phone News

    July 4, 2010 at 6:36 pm

    [...] Tiffany recently made a post on his blog, detailing the encryption features of Windows Phone 7, that will be very useful for the [...]

     
  4. Windows Phone 7 Also Comes With Encryption Methods; Good News for Business Users - A Collection of Latest Happening in Technology Field

    July 5, 2010 at 12:52 pm

    [...] Tiffany recently made a post on his blog, detailing the encryption features of Windows Phone 7, that will be very useful for the [...]

     
  5. Dew Drop – July 7, 2010 | Alvin Ashcraft's Morning Dew

    July 7, 2010 at 5:48 am

    [...] Don’t forget to Encrypt your Windows Phone 7 Data (Rob Tiffany) [...]

     
  6. Tashina Drisko

    July 8, 2010 at 3:17 am

    Thank you ever so for you blog post.Really thank you! Awesome.