安全使用安全字符串作为登录表单

本文关键字:安全 登录 表单 字符串 | 更新日期: 2023-09-27 17:55:08

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

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

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

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

第三个问题;这一切真的有必要吗,还是托管内存环境中 System.String 固有的不安全性有点夸大其词?任何用于存储密码的东西,无论是加密的还是其他的,都应该在操作系统考虑将应用程序交换到虚拟内存之前很久就超出范围并进入垃圾收集器(允许在计算机硬关闭后从交换文件中嗅探密码)。冷启动攻击在理论上是可能的,但实际上,这有多普遍?更大的问题是现在解密的用户数据,它在整个应用程序生命周期中作为用户的一部分徘徊(因此将是使用SecureStrings的主要候选者,因为除了一些基本用法外,它们一直处于休眠状态)。

安全使用安全字符串作为登录表单

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

这是一个不切实际的情况。不要使用SecureString .它几乎没有帮助,并且会偷走您的时间。

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

基本上,您必须设计一个案例,让您的开发人员时间很好地使用 SecureString .

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

现在来看细节:

  • 这个答案为讨论提供了很好的背景。
  • 这是一个使用安全字符串的文本框控件。我没有用了这个所以我不能评论质量,但是在MS博客上我不要指望它只是适当的。
  • 要回答有关将数据传递给System.Security.Crypto的问题,基本上您不能,再多的非托管内存封送也无济于事,因为在此类封送过程中,字符串会被解密。它必须这样做,否则它不能被目标 API 使用。如果您使用的是CSP或X509Certificate,则可以使用SecureSctring,因为它们在框架中受支持,但仅此而已。