从C#中的.NET SecureString读取单个字符?

WPF的PasswordBox返回一个SecureString,它隐藏了snoopers的密码。

问题是你最终必须得到密码的值,而我在网上找到的建议都涉及将值复制到字符串中,这会让你回到窥探者的问题。

IntPtr bstr = Marshal.SecureStringToBSTR(secureString); string password = Marshal.PtrToStringBSTR(bstr); Marshal.FreeBSTR(bstr); 

但是如果你真的想到它,你就不需要这个值作为一个字符串。 我的意思是,你用密码做什么? 您将其哈希,然后将结果与保存的哈希值进行比较,看看它们是否相同。

换句话说,您不需要将SecureString转换为字符串,您只需要能够遍历字符串中的各个字符。

但是怎么样?

如何在CTR中循环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)并将其分配给指针并更新指针以循环遍历字符。

尝试这样的东西我将链接中的lc具有的VB代码示例转换为C#,希望这有助于您开始使用

 Char[] input = "Super Secret String".ToCharArray(); SecureString secret = new SecureString(); for (int idx = 0; idx <= input.Length - 1; idx++) { secret.AppendChar(FileSystem.input(idx)); } SecurePassword.MakeReadOnly(); IntPtr pBStr = Marshal.SecureStringToBSTR(secret); string output = Marshal.PtrToStringBSTR(pBStr); Marshal.FreeBSTR(pBStr); SHA512 sha = new SHA512Managed(); byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(output)); 

这对我有用:

  static char GetChar(SecureString value, int idx) { IntPtr bstr = Marshal.SecureStringToBSTR(value); try { // Index in 2-byte (char) chunks //TODO: Some range validation might be good. return (char)Marshal.ReadByte(bstr, idx * 2); } finally { Marshal.FreeBSTR(bstr); } } 
Interesting Posts