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/

10-13 07:39
查看更多