接下来我将演示如何在Windows Phone 应用程序中运用这两个方法。本文请参考MSDN文档 http://msdn.microsoft.com/zh-cn/library/hh487164(v=VS.92).aspx
创建项目
1. 创建Windows Phone 7项目EncryptionAndDecryptionWP
2. 添加TextBox控件txtData
3. 添加btnStore按钮,用于加密数据,将加密结果保存在内存中
4. 添加btnRetrieve按钮,用于解密数据,并将解密结果用弹出对话框显示。
ContentPanel部分的XAML如下:
< Grid x:Name ="ContentPanel" Grid.Row ="1" Margin ="12,150,12,0" >
< StackPanel Orientation ="Vertical" >
< TextBox x:Name ="txtData" Height ="80" Width ="460" Foreground =" {StaticResource PhoneAccentBrush} " FontSize =" {StaticResource PhoneFontSizeLarge} " />
< Button x:Name ="btnStore" Content ="Store" Height ="71" Width ="160" BorderBrush =" {StaticResource PhoneAccentBrush} " Foreground =" {StaticResource PhoneAccentBrush} " Click ="btnStore_Click" />
< Button x:Name ="btnRetrieve" Content ="Retrieve" Height ="71" Width ="160" BorderBrush =" {StaticResource PhoneAccentBrush} " Foreground =" {StaticResource PhoneAccentBrush} " Click ="btnRetrieve_Click" />
</ StackPanel >
</ Grid >
</ Grid >
加密数据
当单击btnStore后,加密txtData中的数据,并保存在变量中,代码如下:
private void btnStore_Click( object sender, RoutedEventArgs e)
{
var sourceBytes = Encoding.UTF8.GetBytes(txtData.Text.Trim());
_encryptedBytes = ProtectedData.Protect(sourceBytes, null);
}
当单击btnRetrieve后,解密数据,代码如下:
{
if (_encryptedBytes == null) return;
var bytes = ProtectedData.Unprotect(_encryptedBytes, null);
if (bytes != null) MessageBox.Show(Encoding.UTF8.GetString(bytes, 0, bytes.Length));
}
运行结果:输入admin
其它说明:通常情况下,我们需要将加密后的数据保存在独立存储中;Protect与Unprotect的第二个参数是信息熵,可以增加加密的复杂度,可以均为null,同时必须保持一致。
关于WP7平台的安全策略,可以参考MSDN:Windows Phone 安全性
其支持的加密算法包括:AES、HMACSHA1、HMACSHA256、Rfc2898DeriveBytes、RSA、SHA1、SHA256。
还可以参考codeplex上的开源项目:Scrypt RSA Cryptography for Silverlight 3+ and Windows Phone 7
另:.NET Framework中的AES加密通过AesManaged类来操作的,下面的程序使用此类和Rfc2898DeriveBytes类对资料进行加密
代码如下:
public class AESEncryption
{
/// <summary>
/// 加密数据
/// </summary>
/// <param name="dataToEncrypt"> 要加密的字符串 </param>
/// <param name="password"> 密码 </param>
/// <param name="salt"> salt值 </param>
/// <returns></returns>
public static string Encrypt( string dataToEncrypt, string password, string salt)
{
AesManaged aes = null;
MemoryStream stream = null;
CryptoStream cryptoStream = null;
try
{
Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
aes = new AesManaged();
aes.Key = rfc2898.GetBytes(aes.KeySize / 8); // 设置用于对称算法的密钥
aes.IV = rfc2898.GetBytes(aes.BlockSize / 8); // 设置用于对称算法的初始化向量(IV)
stream = new MemoryStream();
// 使用当前的密钥和初始化向量(IV)创建对称加密器对象
cryptoStream = new CryptoStream(stream, aes.CreateEncryptor(), CryptoStreamMode.Write);
byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt);
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(stream.ToArray());
}
finally
{
// 关闭当前流并释放与当前流相关的任何资源
if (cryptoStream != null){
cryptoStream.Close();
}
if (stream != null){
stream.Close();
}
if (aes != null){
// 释放资源
aes.Clear();
}
}
}
/// <summary>
/// 解密数据
/// </summary>
/// <param name="dataToDecrypt"> 需要解密的数据 </param>
/// <param name="password"> 密码 </param>
/// <param name="salt"> salt值 </param>
/// <returns></returns>
public static string Decrypt( string dataToDecrypt, string password, string salt)
{
AesManaged aes = null;
MemoryStream stream = null;
CryptoStream cryptoStream = null;
try
{
Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
aes = new AesManaged();
aes.Key = rfc2898.GetBytes(aes.KeySize / 8); // 设置用于对称算法的密钥
aes.IV = rfc2898.GetBytes(aes.BlockSize / 8); // 设置用于对称算法的初始化向量(IV)
stream = new MemoryStream();
// 使用当前的密钥和初始化向量(IV)创建对称解密器对象
cryptoStream = new CryptoStream(stream, aes.CreateDecryptor(), CryptoStreamMode.Write);
byte[] data = Encoding.UTF8.GetBytes(dataToDecrypt);
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
byte[] decryptBytes = stream.ToArray();
return Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
}
finally
{
// 关闭当前流并释放与当前流相关的任何资源
if (cryptoStream != null)
{
cryptoStream.Close();
}
if (stream != null)
{
stream.Close();
}
if (aes != null)
{
// 释放资源
aes.Clear();
}
}
}
}
参考:http://kosmisch.net/archive/2011/10/25/encrypt_data_in_windows_phone_application.aspx