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/