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.
Meskipun C dibuat untuk memprogram sistem dan jaringan komputer namun bahasa ini juga sering digunakan dalam mengembangkan software aplikasi. C juga banyak dipakai oleh berbagai jenis platform sistem operasi dan arsitektur komputer, bahkan terdapat beberepa compiler yang sangat populer telah tersedia.
C adalah huruf ketiga dalam alfabet Latin. Dalam bahasa Indonesia, huruf ini disebut ce (dibaca [tʃe]).
Bahasa pemrograman C ini dikembangkan antara tahun 1969 – 1972 oleh Dennis Ritchie. Yang kemudian dipakai untuk menulis ulang sistem operasi UNIX. Selain untuk mengembangkan UNIX, bahasa C juga dirilis sebagai bahasa pemrograman umum.
This doesn't have unsafe blocks and won't display the password in plaintext:
public static bool IsEqualTo(this SecureString ss1, SecureString ss2) { IntPtr bstr1 = IntPtr.Zero; IntPtr bstr2 = IntPtr.Zero; try { bstr1 = Marshal.SecureStringToBSTR(ss1); bstr2 = Marshal.SecureStringToBSTR(ss2); int length1 = Marshal.ReadInt32(bstr1, -4); int length2 = Marshal.ReadInt32(bstr2, -4); if (length1 == length2) { for (int x = 0; x < length1; ++x) { byte b1 = Marshal.ReadByte(bstr1, x); byte b2 = Marshal.ReadByte(bstr2, x); if (b1 != b2) return false; } } else return false; return true; } finally { if (bstr2 != IntPtr.Zero) Marshal.ZeroFreeBSTR(bstr2); if (bstr1 != IntPtr.Zero) Marshal.ZeroFreeBSTR(bstr1); } }
Edit: Fixed the leak as recommended by Alex J.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With