http://www.cnblogs.com/lsxqw2004/archive/2009/01/24/1380721.html
从Windows 2000开始,Windows操作系统提供了一套密码学方面的API,称为DPAPI(Data Protection API,数据保护API)。系统中的这套API由crypt32.dll实现,它使用当前用户的登录用户名/密码对来管理密钥。它可以用于标识一个进程、 Windows会话或目前使用的机器,从而在用户、进程、会话或机器级别上加密数据从而确保其机密性。同时使用DPAPI可以使我们不用再负责密钥的管 理。
深入一些,这套API还可以管理对用户密码的修改。例如,如果为某个特定用户将数据加密保存后,即使该用户的密钥发生了变化,仍然可以使用那些数据。这项功能依靠保存过期密钥这一机制实现的。
使用System.Security.Cryptography.ProtectedData类
下面的例子演示了使用System.Security.Cryptography.ProtectedData类在用户级别保护数据。
using System.Security.Cryptography;
class Program{
static void Main() {
string sMsg = "The message to encrypt!" ;
string sEnc, sDec;
System.Text.Encoding utf = new System.Text.UTF8Encoding ();
byte [] entropy = new byte [] { 1, 2, 3, 4, 5, 6, 7, 8 };
{
byte [] bMsg = utf.GetBytes(sMsg);
byte [] bEnc = ProtectedData.Protect(
bMsg , entropy , DataProtectionScope.CurrentUser);
sEnc = System.Convert .ToBase64String(bEnc);
}
{
byte [] bEnc = System.Convert .FromBase64String(sEnc);
byte [] bDec = ProtectedData.Unprotect(
bEnc, entropy, DataProtectionScope.CurrentUser);
sDec = utf.GetString(bDec);
}
System.Console .WriteLine("Message : " + sMsg);
System.Console .WriteLine("Encrypted: " + sEnc);
System.Console .WriteLine("Decrypted: " + sDec);
}
}
可以通过设置DataProtectionScope.LocalMachine值来实现在机器级别保护该数据。本例中为加密添加熵 ,这意味着,即使进程执行的上下文环境符合要求(即处在正确的用户或机器下),如果不知道加密使用的熵也是无法解密数据。即可以把熵值看成某种形式的辅助密钥。
使用System.Security.Cryptography.ProtectedMemory类
使用System.Security.Cryptography.ProtectedMemory类可以获得比ProtectedData类更加精确的保护数据的程度。枚举量MemoryProtectionScope提供了以下选项:
SameProcess: 表示只有处在同一进程中的代码才能将进过加密的数据解密。
SameLogon: 表示只有处在同一用户上下文的代码才能将经过加密的数据解密。
CrossProcess: 表示只要在加密完成后操作系统没有重启,那么在任何进程中执行的任何代码都能将经过加密的数据解密。
下面的示例演示了此类的使用。注意:被加密的数据的字节数必须是16的倍数。
using System.Security.Cryptography;
class Program {
static void Main() {
string sMsg = "01234567890123456789012345678901" ;
System.Text.Encoding utf = new System.Text.UTF8Encoding ();
System.Console .WriteLine("Message : " + sMsg);
byte [] bMsg = utf.GetBytes(sMsg);
ProtectedMemory.Protect( bMsg, MemoryProtectionScope.SameProcess );
System.Console .WriteLine("Encrypted: " + utf.GetString(bMsg));
ProtectedMemory.Unprotect( bMsg, MemoryProtectionScope.SameProcess );
System.Console .WriteLine("Decrypted: " + utf.GetString(bMsg));
}
}
使用System.Security.SecureString类
字符串在内存中的存储是不加密的,而且由于垃圾回收机制,字符串这种引用类型在销毁之前有一段不受控制的时间。如果某些恶意的人能够访问到Windows进程的页面,将这些字符串暴露在外面是很危险的。
为了解决如上问题,.NET Framework提供了SecureString类,其采用DPAPI服务并且允许字符串以加密的形式保存在内存中。
可以通过一个字符数组(使用过后将其设为零)初始化一个SecureString类的实例,或者通过一个字符一个字符的将其构造出来。Marshal类提供了多个方法以供解密一个保存在SecureString类实例中的加密字符串。
下面示例展示了SecureString类的使用:
using System;
using System.Security;
using System.Runtime.InteropServices;
class Program {
static void Main() {
SecureString pwd = new SecureString ();
ConsoleKeyInfo nextKey = Console .ReadKey( true );
while (nextKey.Key != ConsoleKey .Enter) {
pwd.AppendChar( nextKey.KeyChar );
Console .Write( "*" );
nextKey = Console .ReadKey( true );
}
Console .WriteLine();
pwd.MakeReadOnly();
IntPtr bstr = Marshal .SecureStringToBSTR(pwd);
// Get an instance of the Sring class
// only for the example needs.
try { Console .WriteLine( Marshal .PtrToStringAuto(bstr) ); }
finally { Marshal .ZeroFreeBSTR(bstr); }
}
}
使用中往往很难避免将一个SecureString在内存中解密,甚至存放在一个字符串。一定要注意需要在特定的内容区域执行此操作,而写使用完后要尽快销毁,以免出现前文提到的安全问题。
保护特殊文件中的数据
在应用程序的配置文件中常常包含需要加密的设置。.NET中这通过System.Configuration.Configuration类来实现。下面示例演示了在一个名为TagPassword的配置参数中保存经过加密的MyPassword字符串。
using System.Configuration;
class Program {
static void Main() {
SavePwd("MyPassword" );
System.Console .WriteLine(LoadPwd());
}
static void SavePwd(string pwd) {
Configuration cfg = ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None );
cfg.AppSettings.Settings.Add( "TagPassword" , pwd );
cfg.AppSettings.SectionInformation.ProtectSection(
"RsaProtectedConfigurationProvider" );
cfg.Save();
}
static string LoadPwd() {
Configuration cfg = ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None );
return cfg.AppSettings.Settings["TagPassword" ].Value;
}
}
如上,在保存操作的时候需要进行处理,以指定我们希望保存一个加密的版本,而在配置文件被读取的时候加密信息会自动被解密。
本文介绍了如何使用Windows的DPAPI(数据保护API)通过System.Security.Cryptography.ProtectedData和ProtectedMemory类来加密和解密数据。此外,还展示了如何利用SecureString类保护敏感字符串,并在应用程序配置文件中加密设置。
1495

被折叠的 条评论
为什么被折叠?



