安全使用SecureString登录表单

所以这个类似乎很少使用: SecureString 。 它至少从2.0开始就存在,并且有一些SO问题,但我想我会问自己的具体问题:

我有一个LoginForm; 带有用户名和(掩码)密码字段的简单WinForms对话框。 当用户同时输入并单击“登录”时,信息将传递到执行一层键扩展的注入认证类,然后散列一半拉伸键进行validation,而另一半是加密用户的对称密钥帐户数据。 完成所有这些操作后,将关闭loginForm,处理身份validation器类,然后系统继续加载主窗体。 非常标准的东西,可能比标准的哈希 – 密码和比较更多一些,但在我的情况下,简单的哈希密码将通过以明文forms存储用户数据而被打败,因为该数据包括第三个的凭证 – 派对系统(我们都知道人们如何重用密码)。

这是第一个问题; 我如何使用SecureString从密码文本框中检索密码, 而不通过文本框的Text属性将其公开为普通的System.String? 我假设有一种方法可以访问由CLR类包装的Textbox的非托管GDI窗口,并使用Marshal类提取文本数据。 我只是不知道怎么样,而且我似乎无法找到好的信息。

这是第二个问题; 一旦我将密码作为SecureString,我如何从System.Security.Crypto命名空间将其传递给哈希提供程序? 我的猜测是我使用Marshal.SecureStringToBSTR(),然后Marshal.Copy()从返回的IntPtr返回到一个字节数组。 然后我可以调用Marshal.ZeroBSTR()来清理非托管内存,一旦我有哈希,我可以用Array.Clear()将托管数组清零。 如果有一种更简洁的方法可以让我完全控制内存的任何托管副本的生命周期,请告诉我们。

第三个问题; 这一切真的是必要的,还是在管理内存环境中System.String固有的不安全性有点过分了? 用于存储密码(加密或其他方式)的任何内容都应该超出范围并且在操作系统考虑将应用程序交换到虚拟内存之前很久就会进入垃圾收集器(允许在交换文件之后从交换文件中嗅探密码)硬关机的电脑)。 冷启动攻击是一种理论上的可能性,但实际上,这有多常见? 更大的问题是现在解密的用户数据,它在整个应用程序生命周期中作为用户的一部分而挂起(因此将成为使用SecureStrings的主要候选者,因为除了几个基本用法之外,它们保持相当hibernate状态)。

如果您认为自己需要SecureString ,则必须相信攻击者也可以读取您的进程内存。 如果后者为真,他可以在键入时读取密码字符,或直接从文本框内部字符缓冲区读取,或从屏幕上读取像素。

这是一个不切实际的场景。 不要使用SecureString 。 它帮助很少,偷走你的时间。

冷启动攻击更真实,但非常罕见。 它们需要物理机器访问,通常完全拥有机器。 在这种情况下,攻击者阅读是您最不关心的问题。

基本上,您必须设计一个使用SecureString花费您的开发人员时间的情况。

首先,我想表明我同意usr – 不要打扰。

现在详细说明:

  • 这个答案为讨论提供了很好的背景。
  • 这是一个使用SecureString的TextBox控件。 我没有用过这个,所以我不能评论它的质量,但是在MS博客上,我不认为它不是正确的。
  • 要回答有关将数据传递给System.Security.Crypto的问题,基本上你不能也没有多少非托管内存编组会帮助你,因为在这种编组过程中字符串会被解密。 它必须是因为否则它不能被目标API使用。 如果您使用的是CSP或X509Certificate,则可以使用SecureSctring,因为框架支持这些,但这就是它。