Como usar DPAPI com IsolatedStorage na versão Mango do Windows Phone 7
Artigo original publicado em 3 de julho de 2011, domingo
Estava trabalhando na versão Mango do Windows Phone 7 outro dia. Um dos ótimos recursos (há muitos) que foi adicionado é suporte a DPAPI. Um dos casos em que você pode desejar usar isso é para criptografar alguns conteúdos antes de armazená-los localmente. No WP7, quando um aplicativo armazena dados localmente, ele usa algo denominado IsolatedStorage. O sistema IsolatedStorage tem algumas classes agradáveis para ajudar seus aplicativos a ler e gravar nele. Algo que descobri com isso (pelo menos neste ponto) é que ele basicamente não funciona bem com conteúdo criptografado por DPAPI. Deixe-me explicar o que quero dizer com isso.
Suponha que você use a DPAPI para criptografar alguns conteúdos e gravá-los em disco. Agora você deseja ler os dados criptografados de volta, descriptografá-los e fazer algo com eles. Bem, se você seguir a maioria dos exemplos de IsolatedStorage, fará algo como:
//get into isolated storage for the credentials
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
//stream in our registration file
using (var stream = new
IsolatedStorageFileStream(REG_INFO_FILE, FileMode.Open, FileAccess.Read, store))
{
//read the contents into a variable
using (var reader = new StreamReader(stream))
{
//create and fill the byte array with the raw data so you can use it
byte[] rawData = new byte[reader.Length];
reader.Read(rawData, 0, Convert.ToInt16(byteStream.Length));
//now decrypt it
byte[] safeData = ProtectedData.Unprotect(rawData, null);
}
}
}
O problema é que ao chamar Unprotect, você obterá um erro com as linhas de preenchimento sendo adicionadas. O problema são alguns caracteres extras que o leitor padrão de IsolatedStorageFileStream adiciona quando ele lê o conteúdo para você. Para solucionar esse problema, você precisa obter uma referência ao fluxo subjacente e ler diretamente dele. Por exemplo, este código:
//create and fill the byte array with the raw data so you can use it
byte[] rawData = new byte[reader.Length];
reader.Read(rawData, 0, Convert.ToInt16(byteStream.Length));
Deve ser alterado para este:
Stream byteStream = reader.BaseStream;
//create and fill the byte array with the raw data so you can use it
byte[] rawData = new byte[byteStream.Length];
byteStream.Read(rawData, 0, Convert.ToInt16(byteStream.Length));
//now decrypt it
byte[] safeData = ProtectedData.Unprotect(rawData, null);
Assim que você começar a usar o BaseStream, isso deve resolver todos os erros de preenchimento.
Esta é uma postagem de blog traduzida. Consulte o artigo original em Using DPAPI with IsolatedStorage In Windows Phone 7 Mango Release