C#-比较两个SecureStrings是否相等 [英] C# - compare two SecureStrings for equality
问题描述
我有一个带有两个PasswordBox的WPF应用程序,一个用于密码,另一个用于第二次输入密码以进行确认.我想使用PasswordBox.SecurePassword
来获取密码的SecureString
,但是在我接受密码之前,我需要能够比较两个PasswordBoxes的内容以确保相等性.但是,两个相同的SecureString不视为相等:
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
我当时想比较PasswordBoxes的Password
属性会破坏仅访问SecurePassword
的观点,因为我正在读取纯文本密码.在不牺牲安全性的情况下,我该怎么做才能比较这两个密码?
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.
推荐答案
It looks like you could use this to compare the two SecureStrings
.
它使用不安全的代码遍历字符串:
It uses unsafe code to iterate through the strings:
bool SecureStringEqual(SecureString s1, SecureString s2)
{
if (s1 == null)
{
throw new ArgumentNullException("s1");
}
if (s2 == null)
{
throw new ArgumentNullException("s2");
}
if (s1.Length != s2.Length)
{
return false;
}
IntPtr bstr1 = IntPtr.Zero;
IntPtr bstr2 = IntPtr.Zero;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
bstr1 = Marshal.SecureStringToBSTR(s1);
bstr2 = Marshal.SecureStringToBSTR(s2);
unsafe
{
for (Char* ptr1 = (Char*)bstr1.ToPointer(), ptr2 = (Char*)bstr2.ToPointer();
*ptr1 != 0 && *ptr2 != 0;
++ptr1, ++ptr2)
{
if (*ptr1 != *ptr2)
{
return false;
}
}
}
return true;
}
finally
{
if (bstr1 != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(bstr1);
}
if (bstr2 != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(bstr2);
}
}
}
我在下面对其进行了修改,以使其在没有不安全代码的情况下可以工作(请注意,但是在调试时您可以看到纯文本字符串)
I have modified it below to work without unsafe code (note however you are able to see the string in plain text when debugging):
Boolean SecureStringEqual(SecureString secureString1, SecureString secureString2)
{
if (secureString1 == null)
{
throw new ArgumentNullException("s1");
}
if (secureString2 == null)
{
throw new ArgumentNullException("s2");
}
if (secureString1.Length != secureString2.Length)
{
return false;
}
IntPtr ss_bstr1_ptr = IntPtr.Zero;
IntPtr ss_bstr2_ptr = IntPtr.Zero;
try
{
ss_bstr1_ptr = Marshal.SecureStringToBSTR(secureString1);
ss_bstr2_ptr = Marshal.SecureStringToBSTR(secureString2);
String str1 = Marshal.PtrToStringBSTR(ss_bstr1_ptr);
String str2 = Marshal.PtrToStringBSTR(ss_bstr2_ptr);
return str1.Equals(str2);
}
finally
{
if (ss_bstr1_ptr != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(ss_bstr1_ptr);
}
if (ss_bstr2_ptr != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(ss_bstr2_ptr);
}
}
}
这篇关于C#-比较两个SecureStrings是否相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!