WPF PasswordBox 到底有多安全?
How secure is the WPF PasswordBox, really?
我最近已经问了几个关于 PasswordBox
的问题,但我的问题的核心是,我需要一种极其安全的方式来将非常敏感的信息输入到我的 .Net 应用程序中。
开箱即用,WPF PasswordBox
是获取密码或其他敏感信息的首选控件。为了安全起见,它通过 SecurePassword
属性 提供了一个 SecureString
对象,就我而言,这足以满足我的需要。但是,我发现此控件存在一个主要缺陷——它有一个 Password
属性,这是用户在不安全的 .Net 字符串中输入的内容。
我想假设如果我从不在我的应用程序中访问 Password
属性,我的敏感信息的不安全版本将永远不会生成并且必须被垃圾收集。没事。但是,由于字符串的安全形式的要点是保护值免受可以读取 .Net 内存的窥探进程(我假设)的影响,相同的窥探恶意代码是否可以简单地寻找 PasswordBox
在内存中徘徊并找到某种方法来访问 Password
字段,从而使 SecureString
值的使用基本上无用?
我承认,我不知道这些攻击是如何执行的。但是,如果问题是某些应用程序可能正在嗅探您在 .Net 内存 manager/garbage 收集器中的变量,那么在我看来他们所要做的就是访问 PasswordBox
控制对象似乎是合理的,而不是内存中的字符串对象并简单地访问 Password
属性。在这个谜题中我可能遗漏了什么?如果 PasswordBox
包含明文形式的 Password
属性,它又如何安全?
PasswordBox.Password
属性 从 SecurePassword
属性 创建 .NET 字符串,它不会在内部将其存储为字符串。使用 SecureString
的全部意义在于 减少 内存中存在的敏感数据的时间量,并减少该敏感数据的副本数量。您可以在 documentation.
中阅读有关 SecureString
的更多信息
SecureString
是加密的(如果可能的话,通常是这样),所以如果有人只能读取原始内存(比如有人窃取你的内存转储)——他将无法从它。如果您的应用程序受到如此大的破坏,以至于攻击者可以将他自己的 dll 注入您的进程并在那里插入 运行 任意代码 - 那么无论如何您都会遇到更大的问题(并且仍然很有可能密码不会出现在内存中)。
也就是说,在一般情况下使用 PasswordBox
和 SecureString
时,您仍然可以遵循一些合理的准则。
如果您需要访问 PasswordBox.SecurePassword
的结果,请始终处理它:
using (var pwd = myBox.SecurePassword) {
// do stuff
}
这可能看起来很奇怪(处理 属性 返回的东西),但应该这样做,因为这个 属性 returns SecureString
的副本并且应该有而是一种方法,但由于某种原因是 属性.
尽可能少地访问Password
属性,最好只在真正需要时访问一次。您不希望密码副本在内存中保留的时间超过需要的时间。
总是在完成后调用 yourBox.Clear()
。这会将密码设置为空字符串并清除内部 SecureString
内存。
你不必猜测,你可以look it up。
密码框没有字段Password
。它有一个保存密码的字段PasswordTextContainer。
这意味着文档是正确的
Remarks
When you get the Password property value, you expose the password as plain text in memory. To avoid this potential security risk, use the SecurePassword property to get the password as a SecureString.
如果您不以明文形式阅读它并在您的应用程序中将其作为明文保存,它将不会是明文。
但同样,不要相信互联网上随机的人(包括我!),just look at it yourself。
我最近已经问了几个关于 PasswordBox
的问题,但我的问题的核心是,我需要一种极其安全的方式来将非常敏感的信息输入到我的 .Net 应用程序中。
开箱即用,WPF PasswordBox
是获取密码或其他敏感信息的首选控件。为了安全起见,它通过 SecurePassword
属性 提供了一个 SecureString
对象,就我而言,这足以满足我的需要。但是,我发现此控件存在一个主要缺陷——它有一个 Password
属性,这是用户在不安全的 .Net 字符串中输入的内容。
我想假设如果我从不在我的应用程序中访问 Password
属性,我的敏感信息的不安全版本将永远不会生成并且必须被垃圾收集。没事。但是,由于字符串的安全形式的要点是保护值免受可以读取 .Net 内存的窥探进程(我假设)的影响,相同的窥探恶意代码是否可以简单地寻找 PasswordBox
在内存中徘徊并找到某种方法来访问 Password
字段,从而使 SecureString
值的使用基本上无用?
我承认,我不知道这些攻击是如何执行的。但是,如果问题是某些应用程序可能正在嗅探您在 .Net 内存 manager/garbage 收集器中的变量,那么在我看来他们所要做的就是访问 PasswordBox
控制对象似乎是合理的,而不是内存中的字符串对象并简单地访问 Password
属性。在这个谜题中我可能遗漏了什么?如果 PasswordBox
包含明文形式的 Password
属性,它又如何安全?
PasswordBox.Password
属性 从 SecurePassword
属性 创建 .NET 字符串,它不会在内部将其存储为字符串。使用 SecureString
的全部意义在于 减少 内存中存在的敏感数据的时间量,并减少该敏感数据的副本数量。您可以在 documentation.
SecureString
的更多信息
SecureString
是加密的(如果可能的话,通常是这样),所以如果有人只能读取原始内存(比如有人窃取你的内存转储)——他将无法从它。如果您的应用程序受到如此大的破坏,以至于攻击者可以将他自己的 dll 注入您的进程并在那里插入 运行 任意代码 - 那么无论如何您都会遇到更大的问题(并且仍然很有可能密码不会出现在内存中)。
也就是说,在一般情况下使用 PasswordBox
和 SecureString
时,您仍然可以遵循一些合理的准则。
如果您需要访问
PasswordBox.SecurePassword
的结果,请始终处理它:using (var pwd = myBox.SecurePassword) { // do stuff }
这可能看起来很奇怪(处理 属性 返回的东西),但应该这样做,因为这个 属性 returns SecureString
的副本并且应该有而是一种方法,但由于某种原因是 属性.
尽可能少地访问
Password
属性,最好只在真正需要时访问一次。您不希望密码副本在内存中保留的时间超过需要的时间。总是在完成后调用
yourBox.Clear()
。这会将密码设置为空字符串并清除内部SecureString
内存。
你不必猜测,你可以look it up。
密码框没有字段Password
。它有一个保存密码的字段PasswordTextContainer。
这意味着文档是正确的
Remarks
When you get the Password property value, you expose the password as plain text in memory. To avoid this potential security risk, use the SecurePassword property to get the password as a SecureString.
如果您不以明文形式阅读它并在您的应用程序中将其作为明文保存,它将不会是明文。
但同样,不要相信互联网上随机的人(包括我!),just look at it yourself。