C# - 比较两个 SecureString 是否相等
我有一个带有两个密码框的 WPF 应用程序,一个用于密码,另一个用于第二次输入密码以进行确认。我想使用PasswordBox.SecurePassword
来获取密码的SecureString
,但我需要能够比较两个PasswordBox的内容以确保在接受之前相等密码。但是,两个相同的 SecureString 不被认为是相等的:
var secString1 = new SecureString();
var secString2 = new SecureString();
foreach (char c in "testing")
{
secString1.AppendChar(c);
secString2.AppendChar(c);
}
Assert.AreEqual(secString1, secString2); // This fails
我认为比较 PasswordBoxes 的 Password
属性会破坏仅访问 SecurePassword
的点,因为我会阅读纯文本- 文本密码。我应该怎样做才能在不牺牲安全性的情况下比较两个密码?
编辑:根据这个问题,我正在查看这篇博客文章关于“使用 Marshal 类将 SecureString 转换为 ANSI 或 Unicode 或 BSTR ”,那么也许我可以比较这些。
I have a WPF application with two PasswordBoxes, one for the password and another for the password to be entered a second time for confirmation purposes. I was wanting to use PasswordBox.SecurePassword
to get the SecureString
of the password, but I need to be able to compare the contents of the two PasswordBoxes to ensure equality before I accept the password. However, two identical SecureStrings are not considered equal:
var secString1 = new SecureString();
var secString2 = new SecureString();
foreach (char c in "testing")
{
secString1.AppendChar(c);
secString2.AppendChar(c);
}
Assert.AreEqual(secString1, secString2); // This fails
I was thinking comparing the Password
property of the PasswordBoxes would defeat the point of accessing only SecurePassword
because I'd be reading the plain-text password. What should I do to compare the two passwords without sacrificing security?
Edit: based on this question, I'm checking out this blog post about "using the Marshal class to convert the SecureString to ANSI or Unicode or a BSTR", then maybe I can compare those.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
将 @NikolaNovák 的答案翻译为普通的 PowerShell:
Translating @NikolaNovák answer to plain PowerShell:
如果代码在 Windows Vista 或更高版本上运行,则这里是基于 CompareStringOrdinal Windows 函数,因此没有纯文本,所有缓冲区均保持非托管状态。好处是它支持不区分大小写的比较。
If the code is running on Windows Vista or higher, here is a version that's based on the CompareStringOrdinal Windows function, so there's no plain text, all buffers stay unmanaged. Bonus is it supports case-insensitive comparison.
你可以采取不同的方法。我在代码中遇到了同样的问题,即密码和确认的比较,两者都是 SecureString 类型。我意识到最终目标是新密码需要作为 Base-64 字符串存储在数据库中。因此,我所做的只是通过相同的代码传递确认字符串,就像我要将其写入数据库一样。然后,当我有两个 base-64 字符串时,我会在此时比较它们,这是一个简单的字符串比较。
将任何故障一直传达回 UI 层确实需要更多的管道,但最终结果似乎可以接受。希望这段代码足以给出基本的想法。
我是安全编程的新手,所以我欢迎任何改进建议。
You could take a different approach. I hit the same problem in my code, the comparison of a password and a confirmation, both of type SecureString. I realised that the end goal was that the new password needs to be stored in the database as a base-64 string. So what I did was simply pass the confirmation string through the same code as if I were going to write it to the database. Then, when I have two base-64 strings, I compare them at that point, which is a simple string comparison.
It does take a bit more plumbing to communicate any failure all the way back to the UI layer, but the end result seemed acceptable. This code hopefully is enough to give the basic idea.
I am a bit of a newbie at security programming, so I welcome any suggestions for improvement.
这没有不安全的块,也不会以明文形式显示密码:
编辑:按照 Alex J. 的建议修复了泄漏问题。
This doesn't have unsafe blocks and won't display the password in plaintext:
Edit: Fixed the leak as recommended by Alex J.
看来您可以使用 用于比较两个
SecureStrings
。它使用不安全代码来迭代字符串:
我在下面对其进行了修改,使其可以在没有不安全代码的情况下工作(但请注意,在调试时您可以以纯文本形式看到字符串):
It looks like you could use this to compare the two
SecureStrings
.It uses unsafe code to iterate through the strings:
I have modified it below to work without unsafe code (note however you are able to see the string in plain text when debugging):