2

WPFのPasswordBoxは、パスワードをスヌーパーから隠すSecureStringを返します。

問題は、最終的にパスワードの値を取得する必要があることです。ネット上で私が見つけた提案はすべて、値を文字列にコピーすることで、スヌーパーの問題に戻ります。

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

しかし、実際に考えてみると、文字列としての値は実際には必要ありません。つまり、パスワードで何をしますか?それをハッシュしてから、結果を保存されたハッシュと比較し、それらが同じであるかどうかを確認します。

つまり、SecureStringを文字列に変換する必要はなく、文字列内の個々の文字を反復処理できる必要があります。

しかし、どのように?

管理された文字列に変換せずに、C#でBSTRの個々の文字をループするにはどうすればよいですか?

編集:リンクが消えた場合の解決策:

Marshallクラスは、指定されたオフセットでIntPtrから個々のバイトまたはintを抽出できるメソッドを提供します。BSTRオブジェクトには、2つのヌルバイトで終了する16ビット文字の配列が含まれています。したがって、ループすることでそれらにアクセスできます。

byte b = 1;
int i = 0;
while ((char)b != '\0')
{
    b = Marshal.ReadByte(bstr, i);
    // ...
    i += 2;
}

(私はそのフロー制御を気にしません。ダミー値をbに事前入力するのではなく、do ... whileを使用したか、内部ブレークを使用してfor(;;)ループを使用しました。または、長さをループしていると思います。これについては、以下で説明します。)

また、私はおそらく使用します:

short b = Marshal.ReadInt16(bstr, i);

それぞれの下位バイトだけでなく、Unicode文字全体を読み取ります。

BSTRの長さは、次の方法で取得できます。

int len = Marshal.ReadInt32(bstr, -4);

これは、文字数ではなく、ヌルを含まないバイト数です。

また-使用:

Marshal.ZeroFreeBSTR(bstr);
4

3 に答える 3

3

http://weblogs.asp.net/pglavich/archive/2005/08/15/422525.aspx

このリンクは、Marshal.SecureStringToBSTR(secretString)を使用してポインターに割り当て、ポインターを更新して文字をループする方法を示しています。

于 2012-07-12T19:15:25.113 に答える
0

これは私のために働いた:

    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);
        }
    }
于 2016-02-25T01:29:37.347 に答える
-1

このようなものを試してみてください私はlcがC#へのリンクに持っていたVBコードサンプルを変換しましたこれがあなたが始めるのに役立つことを願っています

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));
于 2012-07-12T19:15:47.117 に答える