从C#中的.NET SecureString读取单个字符? [英] Reading single chars from a .NET SecureString in C#?

查看:221
本文介绍了从C#中的.NET SecureString读取单个字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆