WPF的PasswordBox返回一个SecureString,它对侦听器隐藏密码。
问题是您最终必须获得密码的值,而我在网上发现的建议都涉及将密码复制到字符串中,这使您回到侦听器的问题。
IntPtr bstr = Marshal.SecureStringToBSTR(secureString);
string password = Marshal.PtrToStringBSTR(bstr);
Marshal.FreeBSTR(bstr);
但是,如果您真的考虑过它,则实际上并不需要该值,而是一个字符串。我的意思是,您用密码做什么?您对它进行哈希处理,然后将结果与保存的哈希进行比较,看看它们是否相同。
换句话说,您不需要将SecureString转换为字符串,只需要能够遍历字符串中的各个字符即可。
但是如何?
如何在C#中循环遍历BSTR中的各个字符,而不将其转换为托管字符串?
编辑:解决方案,以防链接消失:
Marshall类提供了一些方法,这些方法可以按给定的偏移量从IntPtr中提取单个字节或整数。一个BSTR对象包含一个由两个空字节终止的16位字符数组。因此,您可以通过循环访问它们:
byte b = 1;
int i = 0;
while ((char)b != '\0')
{
b = Marshal.ReadByte(bstr, i);
// ...
i += 2;
}
(我不在乎那个流控制。我会使用do ... while,而不是用一个伪值预填充b,或者我会使用for(;;)循环,并在内部进行中断,否则我会在长度上做个圈,在下面解释如何获得。)
另外,我可能会使用:
short b = Marshal.ReadInt16(bstr, i);
读取整个Unicode字符,而不是每个字符的低字节。
您可以通过以下方式获得BSTR的长度:
int len = Marshal.ReadInt32(bstr, -4);
这是字节数,不包括空值,而不是字符数。
另外-使用:
Marshal.ZeroFreeBSTR(bstr);
最佳答案
http://weblogs.asp.net/pglavich/archive/2005/08/15/422525.aspx
此链接显示如何使用Marshal.SecureStringToBSTR(secretString)并将其分配给指针并更新该指针以遍历字符。
关于c# - 从C#中的.NET SecureString读取单个字符?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11458894/