所以这个类似乎很少使用:SecureString。至少从2.0版开始,有几个SO问题,但我想我会问自己的具体问题:安全使用SecureString登录表格
我有一个LoginForm;带有用户名和(被屏蔽的)密码字段的简单WinForms对话框。当用户同时输入并单击“登录”时,信息被传递给一个注入的认证类,它执行一层密钥扩展,然后将一半的扩展密钥用于验证,而另一半则是加密用户的对称密钥账户数据。当所有这些都完成后,loginForm关闭,处理验证器类,然后系统继续加载主表单。相当标准的东西,可能比标准的hash-the-password-and-compare有更多的参与,但是简单的散列密码在我的情况下会以明文方式存储用户数据,因为这些数据包括第三方密码,第三方系统(我们都知道人们喜欢重复使用密码)。
这是第一个问题;我将如何使用SecureString从密码文本框中检索密码,而不是它通过文本框的Text属性显示为普通的System.String?我假设有一种方法可以访问由CLR类包装的文本框的非托管GDI窗口,并使用Marshal类拉取文本数据。我只是不知道如何,我似乎无法找到好的信息。
这是第二个问题;一旦我将密码作为SecureString使用,我如何将它从System.Security.Crypto命名空间传递给哈希提供程序?我的猜测是,我会使用Marshal.SecureStringToBSTR(),然后Marshal.Copy()从返回的IntPtr返回到一个字节数组。然后,我可以调用Marshal.ZeroBSTR()来清理非托管内存,并且一旦有散列,我就可以用Array.Clear()清零托管数组。如果有一种更清晰的方式可以让我完全控制内存中任何托管副本的生命周期,请告诉。
第三个问题;所有这些都是非常必要的,或者是在托管内存环境中System.String固有的不安全性有点过分?任何用于存储密码,加密或其他方式,应该超出了作用域,并且在操作系统考虑将应用程序交换到虚拟内存之前就已经到达垃圾收集器的路上了(允许从交换文件中嗅探密码在计算机硬关机后)。冷启动攻击是一种理论上的可能性,但真的,这有多常见?更大的担忧是现在解密的用户数据,作为整个应用程序生命周期的用户的一部分而挂起(因此,除了一些基本用法,它们保持相当休眠状态外,它们将成为使用SecureStrings的主要候选项)。
这个想法是减少攻击面。例如,如果攻击者无法读取内存,但可以访问交换文件,SecureString可以提供帮助。我们无法预测攻击者可以做什么或不可以做什么,所以我们试图让事情变得非常困难。但是,没有任何保护措施会有帮助:如果应用程序知道这些信息 - 攻击者可能也可以。 –
我猜对于'SecureString'的最佳论据是开发人员的时间最好花在其他地方。 – usr
好吧,我不必相信攻击者可以看到输入的字符,相信攻击者可以提取交换文件。复杂程度和要求的访问水平是非常不同的。所以,我可以预见SecureString的一个优势是在一个不需要过多设计的情况下需要长期保存在内存中的敏感数据(比如前面提到的第三方系统凭证,只要应用程序能够运行并且最终可以结束交换文件)。但我认为我同意你的观点,即10倍中的9倍比它的价值更麻烦。 – KeithS