Best practice for saving sensitive data in Windows 8

Nick picture Nick · Jan 29, 2012 · Viewed 11.7k times · Source

What's the best way of saving sensitive data to a local file in Windows 8? I'm developing a C# application that needs to store oAuth tokens/passwords. I've heard it was common in .NET to encrypt/decrypt data, but I don't have any experience with those mechanics. Is encryption still recommended/neccesary given that Windows 8 apps have their own personal/protected storage area similar to Windows Phone?

Also, doesn't encrypting/decrypting each time when you request the data causes a performance issue? (would it be better to write a custom/lite algorithm?)

Answer

Robert Levy picture Robert Levy · Jan 29, 2012

UPDATE: Please be aware that while modern/metro apps are restricted from poking at each other's stuff, desktop applications will have unrestricted access to all data stored through these APIs. See http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx which includes code demonstrating this.


Win8 has a new API called PasswordVault that's designed for taking care of all these hard problems for you. Really easy to use, secure, and can be configured by users to roam between their machines so they only have to enter credentials once. I've successfully used this for OAuth tokens

Retrieving credentials (note the stupid exception that WinRT raises... they really should just return null):

const string VAULT_RESOURCE = "[My App] Credentials";
string UserName { get; set; };
string Password { get; set; };
var vault = new PasswordVault();

try
{
   var creds = vault.FindAllByResource(VAULT_RESOURCE).FirstOrDefault();
   if (creds != null)
   {
      UserName = creds.UserName;
      Password = vault.Retrieve(VAULT_RESOURCE, UserName).Password;
   }
}
catch(COMException) 
{
   // this exception likely means that no credentials have been stored
}

Storing credentials:

vault.Add(new PasswordCredential(VAULT_RESOURCE, UserName, Password));

Removing credentials (when the user clicks the logout button in your app):

vault.Remove(_vault.Retrieve(VAULT_RESOURCE, UserName));