The last time I talked to you about Windows Phone security, I showed you how to encrypt your data and save it in Isolated Storage using Silverlight’s AesManaged class to create a Key and an Initialization Vector (IV) based on a password and salt value. This gave your consumer and line-of-business apps the iron-clad AES 256 encryption they needed to secure sensitive data. While this made 3rd-party Windows Phone apps the most secure in the industry, users had to deal with the hassle of entering their credentials each time they launched their secure app.
The reason users had to reenter their credentials each time is because there was no secure way to store those credentials or the key in Isolated Storage. Having the unencrypted credentials used to create the key sitting next to the encrypted data is the same as having no security at all. With the launch of Mango, all this has changed.
Windows Phone 7.5 gives us the Data Protection API (DPAPI) which makes it easy to encrypt and decrypt data. It pulls this off by generating and storing a key based on the user and phone credentials. Oh, and it gets its own decryption key, which is created the first time you run the app that’s doing the encrypting.
Using the ProtectedData class, it’s as simple as calling the Protect method to turn an unencrypted byte array into an encrypted one. On the flip side, you call the Unprotect method to convert an encrypted byte array into an unencrypted one. In cases where the data stays on the phone, this may take care of all of your encryption needs and you won’t necessarily have to jump through all the AesManaged hoops I had you jump through back before we launched Windows Phone 7. On the other hand, if you want to encrypt data on Windows Phone, send it over a network and decrypt it on a server or other endpoint, you need to stick with the stuff I taught you before.
Below is a snippet of code that shows you how to encrypt the password and salt values needed to create a key with the AesManaged class:
//Convert Password and Salt values to byte arrays
byte PasswordByte = Encoding.UTF8.GetBytes(Password.Text);
byte SaltByte = Encoding.UTF8.GetBytes(Salt.Text);
//Encrypt Password and Salt byte arrays using Protect() method
byte ProtectedPasswordByte = ProtectedData.Protect(PasswordByte, null);
byte ProtectedSaltByte = ProtectedData.Protect(SaltByte, null);
//Save byte arrays as two files in Isolated Storage
//Read byte arrays from files
//Decrypt Password and Salt byte arrays using Unprotect() method
byte PasswordByte = ProtectedData.Unprotect(ProtectedPasswordByte, null);
byte SaltByte = ProtectedData.Unprotect(ProtectedSaltByte, null);
//Convert byte arrays to strings and display in the text boxes
Password.Text = Encoding.UTF8.GetString(PasswordByte, 0, PasswordByte.Length);
Salt.Text = Encoding.UTF8.GetString(SaltByte, 0, SaltByte.Length);
With this simple code above, you can now encrypt and decrypt your credentials so you can save them in Isolated Storage next to the portable, encrypted data created via the AesManaged class. So what does this buy you?
It means your users can enter their credentials just once, no matter how many times they launch your secure application. Hassle-free.
Stay safe out there,