×
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.
115 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×