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);
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…