Использование 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