SecureString用于存储在内存中并显示密码?或者是其他东西?

ber*_*rus 10 c# memory security securestring

我一直在为自己编写一个小程序,使用C#,我可以用来存储我的密码,然后检索它们进行查看/编辑.

虽然密码以加密格式存储到磁盘,但当它们被读入内存以便在表单上显示/编辑时,它们是未加密的.

我了解到在内存中使用未加密的密码是一个非常大的安全问题,所以我遇到了这个问题SecureString.

有没有比使用SecureString该类更安全的方法,或者不SecureString辜负它的名字?

svi*_*ick 12

SecureString将文本加密到内存中,您可以在不需要时立即处理它.问题是,当您想要显示它或以几乎任何其他方式使用它时,您必须将其转换为普通字符串,这是不安全的.

此外,我不会太依赖它 - 系统能够在没有任何解密密钥的情况下对其进行解密,这意味着确定的黑客很可能也能够做到这一点.当黑客获得对您计算机的控制权时,您无法确定任何事情,并且他可能能够使用具有良好密钥的良好算法访问未加密的任何内容.


Wes*_*sty 8

SecureString在某种程度上保护了字符串的内存实例,但是你应该知道一些明显的缺点.

  • 可以在没有解密密钥的情况下检索SecureString(就像svick指出的那样),因此任何熟练的黑客都可以轻松地检索这块内存,您可以轻松地执行此次操作来检索纯文本字符串.考虑一下简单性SecureStringToBSTR(input);
  • SecureString需要按字符方式填充,因为没有.Text属性Get或Set accessor要使用.在包括MSDN的博客上,您经常会看到如下代码:

    public static SecureString StringToSecureString(string input)
    {
        SecureString output = new SecureString();
        int l = input.Length;
        char[] s = input.ToCharArray(0, l);
        foreach (char c in s)
        {
            output.AppendChar(c);
        }
        return output;
    }
    
    Run Code Online (Sandbox Code Playgroud)

这段代码的显著问题是,开发商允许的input字符串永远存在于内存中的首位.用于从用户收集此密码的PasswordBox的用户控件或WinForm文本框不应该在一次操作中收集整个密码,如

  • 黑客可以直接访问内存并直接从堆栈上的控件检索密码,或者在此方法实例化时注入代码以检索密码
  • 如果你的最后一次内存转储仍然在你的机器上,从你的最后一个蓝屏,并且这个控件填充了你的纯文本密码,那么密码就坐在一个整洁的小文件中,准备让你的黑客拿起并使用他/她的闲暇.

而是考虑使用KeyPress从用户检索每个字符的选项,否则,WPF的PasswordBox默认支持SecureString我相信(其他人可能会确认这一点).

最后,还有更简单的方法来收集Key Loggers等用户的密码.我的建议是考虑您的用户人口统计,暴露风险,并确定像SecureString 一样微不足道的东西是否真的会削减它.

  • @ScottShaw-Smith,我知道这是旧的,但我不认为他建议使用关键记录器作为"解决这个问题的可行方法".相反,他说如果黑客使用键盘记录器,使用SecureString + KeyPress不会有助于保护密码. (5认同)