在 Windows Phone 7 Mango 版本中將 DPAPI 與 IsolatedStorage 搭配使用
英文原文已於 2011 年 6 月 03 日星期日發佈
前些日子我在 Mango 版本的 Windows Phone 7 上做一些工作。其中已新增的一項卓越功能 (有許多) 是對於 DPAPI 的支援。您可能會想要使用這項功能的其中一種情況是在本機儲存一些內容之前先加密它。在 WP7 中,當應用程式在本機儲存資料時,它會使用稱為 IsolatedStorage 的系統。IsolatedStorage 系統有一些很棒的類別,可協助您的應用程式讀寫。我發現的一件事情是 (至少在此時),它基本上無法與 DAAPI 所加密的內容搭配運作。讓我完整說明我的意思。
假設您使用 DAAPI 加密一些內容,然後將它寫回磁碟。現在您想要將該加密資料讀回、解密它,然後處理它。如果您遵循大部分的 IsolatedStorage 範例,您將執行類似下類命令:
//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);
}
}
}
問題是當您呼叫 Unprotect 時,將會收到錯誤並說明已經新增距離的訊息。這個問題出在於預設 IsolatedStorageFileStream 讀取器在為您讀入內容時,新增了一些額外字元。若要解決此問題,您需要取得基礎資料流的參照,並直接從該參照讀取。例如,這個程式碼:
//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));
應該變更如下:
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);
一旦您開始使用 BaseStream,應該就會修正任何距離錯誤。
這是翻譯後的部落格文章。英文原文請參閱 Using DPAPI with IsolatedStorage In Windows Phone 7 Mango Release