×
Namespaces

Variants
Actions

如何在Windows Phone中加密你的应用程序数据

From Nokia Developer Wiki
Jump to: navigation, search
WP Metro Icon File.png
SignpostIcon WP7 70px.png
Article Metadata

兼容于
文章
翻译:
WS - OtomiiLu
最后由 hamishwillee 在 15 Jul 2013 编辑

本文阐述了如何在 IsolatedStorage 中加密数据,以便增强读取难度。

Contents

简介

IsolatedStorage中的应用程序数据能通过 IsolatedStorageExplorer 工具 (ISETool.exe)读入开发者的计算机中。 对于某些数据而言,这无关紧要。然而,如果你的应用中存储了密码一类的关键数据,那么给予有价值的信息更多保护,就显得有意义了。 本文阐述了如何运用Windows Data Protection API (DPAPI),在数据存入IsolatedStorage 之前加密它们。

加密/解密字符串实例

你所需的只是 System.Security.Cryptography命名空间下的WP7 Silverlight ProtectedData类。 加密类运用DPAPI. DPAPI。DPAPI的加密密钥是从用户和机器的证书中生成的。这保证一个加过密的字符串无法在另外一台机器上被其他用户解密。所以,即使你将加密的机器状态备份到云端----例如SkyDrive----手机丢失或更换后也不会被解密。 我的代码从以下博客中借用了CryptoUtil类: Windows Phone Mango – Encrypt Data.。静态函数 EncryptAndStore()和DecryptString()向独立存储中给定的文件路径存储字符串,或从上述路径载入字符串。 我添加了一个函数: GetHashCode(),以助你为密码计算哈希值。我在应用程序中用这个函数计算用户首次设定密码的哈希值,存入IsolatedStorage,并与用户后续程序调用时给出的字符的哈希值进行对比。 这是修改后的CrytoUtil 类:

public static class CryptoUtil
{
public static string GetHashCode(string p)
{
var a = new SHA256Managed();
return Convert.ToBase64String(a.ComputeHash(new System.Text.UTF8Encoding().GetBytes(p)));
}
/// <summary>
/// Encrypt a string and store it in the phone's isolated storage
/// </summary>
/// <param name="value"></param>
/// <param name="path"></param>
public static void EncryptAndStore(string value, string path)
{
// Convert the string to a byte[].
byte[] PinByte = Encoding.UTF8.GetBytes(value);
// Encrypt the string by using the Protect() method.
byte[] ProtectedBytes = ProtectedData.Protect(PinByte, null);
// Store the encrypted string in isolated storage.
CryptoUtil.WriteProtectedStringToFile(ProtectedBytes, path);
}
/// <summary>
/// Decrypt a string that is stored in the phone's isolated storage in the provided path
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string DecryptString(string path)
{
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!file.FileExists(path)) return string.Empty;
}
// Retrieve the string from isolated storage.
byte[] ProtectedPinByte = CryptoUtil.ReadStringFromFile(path);
// Decrypt the string by using the Unprotect method.
byte[] PinByte = ProtectedData.Unprotect(ProtectedPinByte, null);
// Convert the PIN from byte to string and display it in the text box.
return Encoding.UTF8.GetString(PinByte, 0, PinByte.Length);
}
private static void WriteProtectedStringToFile(byte[] strinData, string path)
{
// Create a file in the application's isolated storage.
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageFileStream writestream = new IsolatedStorageFileStream(path, System.IO.FileMode.Create, System.IO.FileAccess.Write, file);
// Write stringData to the file.
Stream writer = new StreamWriter(writestream).BaseStream;
writer.Write(strinData, 0, strinData.Length);
writer.Close();
writestream.Close();
}
}
private static byte[] ReadStringFromFile(string path)
{
// Access the file in the application's isolated storage.
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageFileStream readstream = new IsolatedStorageFileStream(path, System.IO.FileMode.Open, FileAccess.Read, file);
// Read the PIN from the file.
Stream reader = new StreamReader(readstream).BaseStream;
byte[] pinArray = new byte[reader.Length];
reader.Read(pinArray, 0, pinArray.Length);
reader.Close();
readstream.Close();
return pinArray;
}
}
}

为字符串以外的数据加密

有时你需要存储的不仅仅是一个字符串,在这种情况下你可以用JSON串行器 DataContractJsonSerializer (在System.Runtime.Serialization.Json 命名空间下) 来存储完整的对象。你需要将 System.Runtime.Serialization.dll andSystem.ServiceModel.Web.dll引入命名空间。我的例子中,需要保存完整的DataModel。我用JSON格式来将数据存入字符串,然后将文件加密成iso存储。 这是我 Application_Closing()处理器中的代码:

private void Application_Closing(object sender, ClosingEventArgs e)
{
var ser = new DataContractJsonSerializer(typeof(DataModel));
MemoryStream stream1 = new MemoryStream();
ser.WriteObject(stream1, data);
string objects = Encoding.UTF8.GetString(stream1.GetBuffer(), 0, (int)stream1.Length);
CryptoUtil.EncryptAndStore(objects, "keys");
}
用下列 Application_Launching 中的代码,你能够解密数据:
private void Application_Launching(object sender, LaunchingEventArgs e)
{
reactivated = false;
if (!IsolatedStorageFile.GetUserStoreForApplication().FileExists("keys"))
data = new DataModel();
string parms = CryptoUtil.DecryptString("keys");
if (parms.Length > 0)
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(parms)))
{ //parse into jsonser
var ser = new DataContractJsonSerializer(typeof(DataModel));
data = (DataModel)ser.ReadObject(ms);
}
}

总结

给出的类能够简化Windows Phone 7上的数据加密。它很易用,也不会降低性能。

This page was last modified on 15 July 2013, at 14:29.
97 page views in the last 30 days.