【发布时间】:2012-07-12 19:07:53
【问题描述】:
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);
【问题讨论】:
-
你试过for循环还是foreach循环..???
-
他在 C# 中这样做我假设不是 VB lc
-
该示例完全符合我的要求,它将字符串复制到托管字符串中。
标签: c# bstr securestring