Использование DPAPI с IsolatedStorage в выпуске Windows Phone 7 Mango

Дата публикации исходной статьи: воскресенье, 3 июля 2011 г.

Недавно я работал над выпуском Windows Phone 7 Mango.  Одной из замечательных возможностей (которых множество), добавленных в эту версию, является поддержка DPAPI.  Один из случаев использования этой возможности — шифрование контента перед его локальным сохранением.  В WP7 при локальном сохранении данных приложение использует некий объект, называемый IsolatedStorage.  Система IsolatedStorage имеет несколько полезных классов, помогающих приложениям читать и записывать данные.  Однако я обнаружил одну интересную особенность (по крайней мере на данный момент) — эта система по существу не работает с контентом, зашифрованным DPAPI.  Сейчас я объясню, что я имею в виду.

Предположим, что вы использовали DPAPI для шифрования контента, а затем записали его на диск.  Теперь вы хотите прочитать зашифрованные данные, расшифровать их и использовать в дальнейших действиях.  Итак, если следовать большинству примеров использования IsolatedStorage, нужно сделать следующее:

//войти в изолированное хранилище для получения учетных данных
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
 //открыть поток файла регистрации
 using (var stream = new
  IsolatedStorageFileStream(REG_INFO_FILE, FileMode.Open, FileAccess.Read, store))
 {
  //считать содержимое в переменную
  using (var reader = new StreamReader(stream))
  {
   //создать и заполнить массив байтов неформатированными данными, чтобы их можно было использовать
   byte[] rawData = new byte[reader.Length];
   reader.Read(rawData, 0, Convert.ToInt16(byteStream.Length));

   //расшифровать данные
   byte[] safeData = ProtectedData.Unprotect(rawData, null);
  }
 }
}

Проблема в том, что при вызове метода Unprotect вы получите ошибку и сообщение о том, что к данным были добавлены заполнители.  Проблема в нескольких дополнительных символах, которые добавляет стандартный считыватель IsolatedStorageFileStream при считывании контента.  Чтобы обойти эту проблему, нужно получить ссылку на основной поток и считывать данные прямо из него.  Например, этот код:

//создание и заполнение массива байтов неформатированными данными для их последующего использования
byte[] rawData = new byte[reader.Length];
reader.Read(rawData, 0, Convert.ToInt16(byteStream.Length));

Следует изменить следующим образом:

Stream byteStream = reader.BaseStream;                               

//создание и заполнение массива байтов неформатированными данными для их последующего использования
byte[] rawData = new byte[byteStream.Length];
byteStream.Read(rawData, 0, Convert.ToInt16(byteStream.Length));

//расшифровка данных
byte[] safeData = ProtectedData.Unprotect(rawData, null);

При использовании метода BaseStream ошибки заполнения будут устранены.

 

Это локализованная запись блога. Исходная статья доступна по адресу Using DPAPI with IsolatedStorage In Windows Phone 7 Mango Release