1

標準のシステム ダイアログを表示して、ユーザーにアカウントのユーザー名とパスワードを要求し、この情報を使用してこれらの資格情報でプロセスを開始したいと思います。

CredUIPromptForCredentialsそのダイアログを表示する機能を指摘されました。ユーザー名とパスワードを文字列として返します。しかし、ProcessStartInfo構造はパスワードとしてSecureString.

パスワードを文字列として使用し、それを文字ごとに変換できることを理解していますSecureString(そのための単一の関数はありません) SecureString

CredUIPromptForCredentialsしたがって、管理されていない呼び出しからSecureString.NETのようにパスワードを直接受け入れる方法が必要だと思います。結局のところ、アプリケーションでパスワードにアクセスする必要はまったくありません。別のプロセスを開始するために使用されることになっているだけで、すぐに忘れることができます。

では、私の P/Invoke 宣言はCredUIPromptForCredentialsどのように見えるSecureStringでしょうか? (私は C# 用の pinvoke.net のものから始めました。)

更新:ああ、もし誰かがCredUIPromptForWindowsCredentialsWindows Vista/7 の新機能の例を持っていれば、それも素晴らしいだろう.

4

1 に答える 1

2

IntPtrアンマネージ文字列バッファーの をコンストラクターにキャストしchar*て使用できます。SecureString(char*, int)

// somehow, we come into posession of an IntPtr to a string
// obviously, this would be a foolish way to come into it in
// production, since stringOriginalContents is already in managed
// code, and the lifetime can therefore not be guaranteed...
var stringOriginalContents = "foobar";
IntPtr strPtr = Marshal.StringToHGlobalUni(stringOriginalContents);
int strLen = stringOriginalContents.Length;
int maxLen = 100;

// we copy the IntPtr to a SecureString, and zero out the old location
SecureString ssNew;
unsafe
{
    char* strUPtr = (char*)strPtr;

    // if we don't know the length, calculate
    //for (strLen = 0; *(strUPtr + strLen) != '\0' 
    //    // stop if the string is invalid
    //    && strLen < maxLen; strLen++)
    //    ;

    ssNew = new SecureString((char*)strPtr, strLen);

    // zero out the old memory and release, or use a Zero Free method
    //for (int i = 0; i < strLen; i++)
    //    *(strUPtr + i) = '\0';
    //Marshal.FreeHGlobal(strPtr);
    // (only do one of these)
    Marshal.ZeroFreeGlobalAllocUnicode(strPtr);
}

// now the securestring has the protected data, and the old memory has been
// zeroed, we can check that the securestring is correct.  This, also should
// not be in production code.
string strInSecureString =
    Marshal.PtrToStringUni(
    Marshal.SecureStringToGlobalAllocUnicode(ssNew));
Assert.AreEqual(strInSecureString, stringOriginalContents);
于 2013-06-06T18:39:43.483 に答える