Usar DPAPI con IsolatedStorage en la versión Mango de Windows Phone 7

Artículo original publicado el domingo, 3 de julio de 2011

El otro día estuve trabajando un poco en la versión Mango de Windows Phone 7. Una de las excelentes características (hay muchas) que agregaron es la compatibilidad con DPAPI. Uno de los casos en los que le puede servir es cuando desea cifrar contenido antes de almacenarlo localmente. En WP7, cuando una aplicación almacena datos localmente usa algo llamado IsolatedStorage. El sistema IsolatedStorage tiene unas prácticas clases para ayudar a sus aplicaciones a leer y escribir en él. Sin embargo, una cosa que descubrí (al menos en este punto) es que en realidad fundamentalmente no trabaja con contenido cifrado por DPAPI. Veamos a qué me refiero.

Suponga que usa DPAPI para cifrar contenido y luego escribir en el disco. Ahora desea volver a leer esos datos cifrados, descifrarlos y hacer algo con ellos. Bien, si sigue la mayoría de ejemplos de IsolatedStorage, hará algo como lo siguiente:

//entre a isolated storage para las credenciales
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
 //transmita en secuencia nuestro archivo de registro
 using (var stream = new
  IsolatedStorageFileStream(REG_INFO_FILE, FileMode.Open, FileAccess.Read, store))
 {
  //lea el contenido de una variable
  using (var reader = new StreamReader(stream))
  {
   //cree y complete la matriz de bytes con los datos sin procesar para poder usarla
   byte[] rawData = new byte[reader.Length];
   reader.Read(rawData, 0, Convert.ToInt16(byteStream.Length));

   //ahora descífrela
   byte[] safeData = ProtectedData.Unprotect(rawData, null);
  }
 }
}

El problema es que cuando llame a Unprotect obtendrá un error a lo largo de las líneas de relleno que se hayan agregado. El problema es algunos caracteres extra que el lector IsolatedStorageFileStream predeterminado agrega cuando lee contenido. Para solucionar alternativamente este problema, debe obtener una referencia a la transmisión en secuencia subyacente y leer directamente desde allí. Por ejemplo, este código:

//cree y complete la matriz de bytes con los datos sin procesar para poder usarla
byte[] rawData = new byte[reader.Length];
reader.Read(rawData, 0, Convert.ToInt16(byteStream.Length));

Debe cambiarse así:

Stream byteStream = reader.BaseStream;                               

//cree y complete la matriz de bytes con los datos sin procesar para poder usarla
byte[] rawData = new byte[byteStream.Length];
byteStream.Read(rawData, 0, Convert.ToInt16(byteStream.Length));

//ahora descífrela
byte[] safeData = ProtectedData.Unprotect(rawData, null);

Una vez que comience a usar la BaseStream, se deben solucionar los errores de relleno.

 

Esta entrada de blog es una traducción. Puede consultar el artículo original en Using DPAPI with IsolatedStorage In Windows Phone 7 Mango Release