【发布时间】:2013-09-06 02:11:51
【问题描述】:
我正在一个项目中实施 SecureString。在阅读它并看到很多基本上做同样事情的例子之后,我一直认为有些地方是错误的。
以下面的代码为例:
public static string ToUnsecureString(this SecureString secureString)
{
if(secureString == null)
throw new ArgumentNullException("secureString");
IntPtr unmanagedString = IntPtr.Zero;
try
{
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
return Marshal.PtrToStringUni(unmanagedString);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}
}
保护数据固然很好,但最终它再次被设置为标准字符串的真正意义何在?
我知道您可以将密码存储在char[] 中,然后在创建SecureString 后将其清零,但是在检索字符串时我应该怎么做?我没有看到将其作为char[] 检索的方法,并且不会只调用.ToCharArray() 仍将Marshal.PtrToStringUni(...) 返回的字符串留在内存中吗?
我只是错过了一些非常基本的东西吗?谢谢。
【问题讨论】:
-
当您不得不再次取出钱时,将钱存入银行有什么意义?关键是它在那里时是安全的。这个问题对我来说很奇怪;问题基本上是“我从它所在的安全盒子中取出了一些东西,现在它没有安全保障,那么为什么我首先要把它放在盒子里?”我不知道;你告诉我。如果你打算把它拿出来,为什么要把它放在一个安全的盒子里?
-
@EricLippert 我了解你来自哪里,我会用你的例子作为我提问的理由(这可能是有缺陷的)。是的,一旦物品从安全盒中取出,它就是不安全的。但是,您始终可以将物品放回盒子中。由于字符串是不可变的,即使在方法返回之后,它们是否也不会在内存中存储很长一段时间?如果我弄错了,请告诉我,我会继续删除这个问题。谢谢
-
关键是你永远不会把它放到托管字符串中。要么直接在低级代码中使用它,要么将数据复制到一个 mutable 数组,在使用后直接擦除(但由于 GC 在内存中移动对象,即使这样也很棘手)
-
关于
SecureString的另一个重要点是,它只是为了让字符串远离故障转储、交换文件等。而不是为了保护字符串免受用户或恶意进程的影响。 -
“没有找到将其检索为 char[] 的方法”
Marshal.Copy呢?
标签: c# .net security securestring