从C#中的.NET SecureString读取单个字符? [英] Reading single chars from a .NET SecureString in C#?
问题描述
WPF的PasswordBox返回一个SecureString,它对窥探者隐藏密码。
WPF's PasswordBox returns a SecureString, which hides the password from snoopers.
问题是您最终必须获得密码的值,以及我的建议在网上发现所有内容都涉及将值复制到字符串中,这使您回到侦听器的问题。
The problem is that you eventually have to get the value of the password, and the suggestions I've found on the net all involve copying the value into a string, which gets you back to the problem of snoopers.
IntPtr bstr = Marshal.SecureStringToBSTR(secureString);
string password = Marshal.PtrToStringBSTR(bstr);
Marshal.FreeBSTR(bstr);
但是,如果您真的考虑过,您并不需要字符串作为该值。我的意思是,您用密码做什么?对其进行哈希处理,然后将结果与保存的哈希进行比较,看看它们是否相同。
But if you really think about it, you don't really need the value, as a string. I mean, what do you do with a password? You hash it and then compare the result to a saved hash, and see if they are the same.
换句话说,您无需将SecureString转换为字符串,您只需要能够遍历字符串中的各个字符。
In other words, you don't need to convert the SecureString into a string, you just need to be able to iterate over the individual characters in the string.
但是如何?
如何在C#中循环遍历BSTR中的各个字符,而不将其转换为托管字符串?
How do I loop over the individual characters in a BSTR, in C#, without converting it to a managed string?
编辑:解决方案,以防链接消失:
EDITING: the solution, in case the link disappears:
Marshall类提供了一些方法,这些方法可以按给定的偏移量从IntPtr中提取单个字节或整数。一个BSTR对象包含一个由两个空字节终止的16位字符数组。因此,您可以通过循环访问它们:
The Marshall class provides methods that can extract individual bytes or ints from an IntPtr, at given offsets. A BSTR object contains an array of 16-bit characters, terminated by two null bytes. So you can access them by looping:
byte b = 1;
int i = 0;
while ((char)b != '\0')
{
b = Marshal.ReadByte(bstr, i);
// ...
i += 2;
}
(我不在乎这种流量控制。我曾经使用过一个do ...同时,而不是用一个虚拟值预填充b,或者我使用了带有内部中断的for(;;)循环,或者我循环了长度,这我将解释如何获得,如下。)
(I don't care for that flow control. I'd have used a do...while, rather than prepopulate b with a dummy value, or I'd have used a for(;;) loop, with internal breaks, or I'd have looped on the length, which I explain how to get, below.)
此外,我可能还会使用:
Also, I'd probably use:
short b = Marshal.ReadInt16(bstr, i);
读取整个Unicode字符,而不仅仅是读取每个字符的低字节。
Reading the entire unicode chars, instead of just the low bytes of each.
您可以通过以下方式获取BSTR的长度:
You can get the length of the BSTR with:
int len = Marshal.ReadInt32(bstr, -4);
这是字节数,不包括空值,而不是字符数。
This is the number of bytes, not including the nulls, not the number of chars.
也-使用:
Marshal.ZeroFreeBSTR(bstr);
推荐答案
http://weblogs.asp.net/pglavich/archive/2005/08/15/422525.aspx
此链接显示了如何使用Marshal.SecureStringToBSTR(secretString)并将其分配给指针并更新该指针以遍历字符。
This link shows how to use Marshal.SecureStringToBSTR(secretString) and assign it to a pointer and update the pointer to loop over the characters.
这篇关于从C#中的.NET SecureString读取单个字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!