惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
Recent Announcements
Recent Announcements
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
酷 壳 – CoolShell
酷 壳 – CoolShell
J
Java Code Geeks
V
V2EX
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
博客园 - Franky
爱范儿
爱范儿
T
Tailwind CSS Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
博客园_首页
B
Blog RSS Feed
博客园 - 司徒正美
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - Sherrys

Content-Type 参数 Sql 2000 中行转列的查询方法 DotNet Framework 小技巧 通过 INotifyPropertyChanged 实现观察者模式 API参数说明符前缀详解 C#中调用Windows API的要点 - Sherrys - 博客园 SQL 处理简单的 Xml Special Considerations When Using Query Notifications 利用.NET Framework使用RSS feed SQL远程连接 SQL 事务的隔离 SELECT 语句收藏(2000 & 2005) 自动处理 SQL 2005 表格数据 SQL事务的使用 用JS让文章内容指定的关键字加亮 - Sherrys - 博客园 查询SQL连接数的方法 对象的继承方案 使用 ICallbackEventHandler aspx页面中的DropDownList 的 SelectValue 出现中文导致不回调方法的问题 如何利用SQL Server 2005数据库快照形成报表
使用 .NET 2.0 SecureString 类保护敏感数据
Sherrys · 2007-06-22 · via 博客园 - Sherrys

什么时候应当使用SecureString类

你可能感到怀疑,既然可以使用基本的String类,为什么还有必要使用SecureString类呢?问题在于String类的设计方面。例如,如果你有一个String类的实例包含某个人的社会安全号,你就希望应用程序在处理过程中将其安全保存,以避免泄露。

问题的关键在于安全保存文本,因为String类将其以明文形式保存。查明数据的保存位置需要对.NET字符串有一定了解。.NET字符串是不可变的。也就是说,字符串值的每一个变化都在内存中建立一个新的字符串。因此,内存中的各种敏感数据可能会被不严格的代码或用户访问。

这并不是说明为什么使用StringBuilder对象的最有效方法和解释。由于垃圾收集功能,你可能认为这并不是一个太大的问题,但利用.NET垃圾收集使用字符串恢复内存没有确定性。因此,如果数据确实十分敏感,你应当避免String类,而选择SecureString类这些其它方法。

SecureString类具有以下特性:

  • 它对保存在内存中的字符串值进行加密。它利用数据保护API(DPAPI),因此它只能在基于NT的平台上使用。

  • SecureString类遵循IDisposable模式。

  • 加密文本不能被轻易解密;也就是说,不存在可以迅速阅读字符串内容的ToString类(没人说过加密很容易)。

一个简单的事例:

System.Security.SecureString ss = new System.Security.SecureString();

ss.AppendChar('T');

ss.AppendChar('e');

ss.AppendChar('c');

ss.AppendChar('h');

ss.AppendChar('R');

ss.AppendChar('e');

ss.AppendChar('p');

ss.AppendChar('u');

ss.AppendChar('b');

ss.AppendChar('l');

ss.AppendChar('i');

ss.AppendChar('c');

ss.AppendChar('.');

ss.AppendChar('c');

ss.AppendChar('o');

ss.AppendChar('m');

Console.WriteLine(ss);

增加最后一个字符后,以上代码用MakeReadOnly方法锁定字符串值。这意味着这个值不能被修改。使数据只读后,一旦你企图修改数据,就会出现异常。你会注意到,在执行时,代码只显示类的名称(System.Security.SecureString)。

获得数据

像.NET Framework的大多数对象一样,SecureString类也提供一个ToString方法。但是,ToString方法源于基本的System.Object类,在SecureString类中它不能被忽略。因此,调用SecureString类的ToString方法只显示对象(System.Security.SecureString)的类型,而没有实际的值。

应用SecureString类的难点在于如何恢复保存在其中的数据。因为它使用Windows的加密服务,要利用它,你需要使用System.Runtime命名空间。下面的C#代码是恢复数据的第一个步骤。它将SecureString类的内容复制到一个长指针对象中。

IntPtr pointerName = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(SecureString object);

    植入指针对象后,指针通过System.Runtime.InteropServices.Marshal类转换为一个字符串。这一操作由以下C#代码完成:

Console.WriteLine(System.Runtime.InteropServices.Marshal.PtrToStringBSTR(bstr));

微软文件指出,转换对象到一个指针分配了一个字符串所需的未管理内存,因此任务完成后你应当总是通过调用ZeroFreeBSTR方法释放指针对象,如以下的C#所示:

    System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(bstr);

下面的C#代码将在SecureString对象中保存数据与恢复数据、保存和显示内容的例子结合起来:

System.Security.SecureString ss = new System.Security.SecureString();

ss.AppendChar('T');

ss.AppendChar('e');

ss.AppendChar('c');

ss.AppendChar('h');

ss.AppendChar('R');

ss.AppendChar('e');

ss.AppendChar('p');

ss.AppendChar('u');

ss.AppendChar('b');

ss.AppendChar('l');

ss.AppendChar('i');

ss.AppendChar('c');

ss.AppendChar('.');

ss.AppendChar('c');

ss.AppendChar('o');

ss.AppendChar('m');

Console.WriteLine(ss);

IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(ss);

try

{

Console.WriteLine(System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr));

}

finally

{

System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);

}