最近,我已经围绕PasswordBox提出了几个问题,但是从我的问题的核心出发,我需要一种非常安全的方式来将非常敏感的信息输入到.Net应用程序中。

WPF PasswordBox开箱即用,可用来控制密码或其他敏感信息的获取。为了安全起见,它通过SecureString属性提供了一个SecurePassword对象,在我看来,该属性足以满足我的需求。但是,我发现此控件存在一个主要缺陷-它具有Password属性,该属性是用户在不安全的.Net字符串中输入的内容。

我想假设,如果我从不访问应用程序中的Password属性,将永远不会生成敏感信息的不安全版本,而必须对其进行垃圾收集。没事。但是,由于字符串的安全形式的要点是保持值的安全以防止可读取.Net内存的监听进程(我认为),因此相同的监听恶意代码是否可以简单地查找在其中徘徊的PasswordBox内存并找到某种方法来访问Password字段,从而使SecureString值的使用基本上无用?

我承认,我不知道如何利用这些漏洞。但是,如果问题在于某些应用程序可能正在.Net内存管理器/垃圾收集器中嗅探您的变量,那么对我来说,他们所要做的就是访问PasswordBox控制对象而不是字符串对象,这似乎是合理的。在内存中,只需访问Password属性。在这个难题中我可能会缺少什么?如果PasswordBox包含明文形式的Password属性,那么如何安全?

最佳答案

PasswordBox.Password属性从SecurePassword属性创建.NET字符串,它不会在内部将其存储为字符串。使用SecureString的全部目的是减少内存中存在感测数据的时间,并减少该感测数据的副本数量。您可以在documentation中阅读有关SecureString的更多信息。
SecureString是加密的(如果可能,通常是加密的),因此,如果某人只能读取原始内存(例如某人窃取了您的内存转储),则他将无法从中读取密码。如果您的应用程序受到严重威胁,攻击者可以将自己的dll注入(inject)您的进程中并在其中运行任意代码-则无论如何您都会遇到更大的问题(而且仍然很有可能密码已经不在内存中了)。

也就是说,在通常使用PasswordBoxSecureString时,您仍然可以遵循一些合理的准则。

  • 如果需要访问PasswordBox.SecurePassword,请务必对其进行处理:
    using (var pwd = myBox.SecurePassword) {
        // do stuff
    }
    

  • 这可能看起来很奇怪(处理由属性返回的内容),但是应该这样做,因为此属性返回SecureString的副本,并且应该是方法,但出于某种原因是属性。
  • 尽可能少地访问Password属性,最好在您真正需要它时才访问它。您不希望密码副本保留在内存中的时间超过所需的时间。
  • 完成后,请始终调用yourBox.Clear()。这会将密码设置为空字符串,并清除内部SecureString内存。
  • 关于c# - WPF PasswordBox到底有多安全?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47576612/

    10-11 10:58