安全使用SecureString登录表单

Kei*_*thS 20 c# security securestring

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

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

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

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

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

usr*_*usr 10

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

这是一个不切实际的场景.不要用SecureString.它有助于减少和窃取你的时间.

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

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

  • 这个想法是减少攻击面.例如,如果攻击者无法读取内存但可以访问交换文件,则SecureString可以提供帮助.我们永远无法预测攻击者能做什么或不能做什么,所以我们试图让他们最困难.但是,没有多少保护可以帮助:如果应用知道信息 - 攻击者可能也可以. (7认同)
  • @usr您不向用户出售`SecureString`,而是销售"安全功能".有.Net API使用SecureString和WPF的`PasswordBox`在内部使用它(并通过属性公开它),这可以减轻痛点,至少在你可以为你的UI使用WPF和说.Net API的情况下.因此,我仍然坚持认为反对它通常是不好的建议 (3认同)
  • 好吧,我不必相信攻击者可以看到输入的字符,相信攻击者可以提取交换文件.复杂程度和所需访问程度非常不同.因此,我可以预见SecureString在一个不太费人的情况下需要长期保存在内存中的敏感数据(就像前面提到的第三方系统凭证一样,只要应用程序存在并且可能最终存在交换文件).但我认为我同意你的观点,即10次中的9次比它的价值更麻烦. (2认同)

And*_*ykh 6

首先,我想声明我同意 usr 的观点 - 不要打扰。

现在详细说明:

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