2013-04-14 33 views
1

我想顯示標準系統對話框,要求用戶輸入用戶名和密碼來使用這些信息來啓動一個使用這些憑據的進程。從SecureString .NET的CredUIPromptForCredentials

我已經指出CredUIPromptForCredentials函數顯示對話框。它以字符串形式返回用戶名和密碼。但ProcessStartInfo結構預計密碼爲SecureString

據我所知,我現在可以使用密碼作爲字符串,並將其轉換爲SecureString字符(不存在單一功能) - 但它會完全破壞SecureString背後的想法。

所以我想必須有一些方法可以直接接受來自非管理調用的密碼,CredUIPromptForCredentials在.NET中爲SecureString。畢竟,我真的不需要以任何方式在我的應用程序中訪問密碼。它只是用來啓動另一個過程,然後可以儘快被遺忘。

那麼CredUIPromptForCredentials的P/Invoke聲明如何看起來像SecureString? (我已經開始與一個來自pinvoke.net爲C#。)

更新:哦,如果有人有新功能CredUIPromptForWindowsCredentials在Windows Vista/7,這將是很酷的例子還有,因爲我現在甚至無法弄清楚如何使用它。

+1

可能重複http://stackoverflow.com/questions/4134882/show-authentication-dialog-in-c-sharp-for-windows-遠景-7) –

回答

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); 
[在C#中爲Windows Vista/7顯示身份驗證對話框(的