2013-07-28 86 views
6

一個過程中,我知道,你可以用下面的方式給定的用戶名/密碼運行進程:開始使用用戶名和密碼

var processInfo = new ProcessStartInfo 
    { 
     WorkingDirectory = workingDirectory, 
     FileName = "a name", 
     UserName = loggedUserName, 
     Password = "password", 
     Domain = userNameDomain, 
     UseShellExecute = false, 
    }; 
    Process.Start(processInfo); 

我現在面臨的問題是,我不希望將實際密碼寫入代碼的一部分,並且如果我將Password屬性留空,則該過程將無法啓動...如何在不將密碼暴露爲代碼中的硬編碼字符串的情況下安全地啓動該過程?

+0

的ProcessStartInfo的密碼屬性是SecureString的。您不能簡單地以這種方式編寫它 – Steve

+0

您可以將其存儲在文件/數據庫中,該文件/數據庫將在程序啓動時讀取。您也可以通過依賴文件的簡單方法來加密它(http://stackoverflow.com/questions/740812/whats-the-easiest-way-to-encrypt-a-file-in-c)或依靠關於數據庫的內置函數(http://dev.mysql.com/doc/refman/5.0/es/set-password.html)。 – varocarbas

回答

5

ProcessStartInfo.Password不是一個簡單的字符串,您可以記下並分配給該屬性。你需要的是一個SecureString實例,並且無法創建一個SecureString傳遞一個簡單的字符串給它的構造函數。顯然,操作系統沒有API或方法,允許非信任程序檢索當前用戶的密碼(這將是有史以來最大的安全漏洞)。

所以,在我看來,你只剩下一個選擇。問問你的用戶重新輸入密碼,所產生的輸入應轉化爲SecureString的

這個例子是字符串類I have seen here

using System.Security; 

// ... 

public static SecureString ConvertToSecureString(this string password) 
{ 
    if (password == null) 
     throw new ArgumentNullException("password"); 

    unsafe 
    { 
     fixed (char* passwordChars = password) 
     { 
      var securePassword = new SecureString(passwordChars, password.Length); 
      securePassword.MakeReadOnly(); 
      return securePassword; 
     } 
    } 
} 

你可以用它來轉換輸入的密碼的擴展方法由您的用戶啓動並啓動該過程

using(frmGetPassword fgp = new frmGetPassword()) 
{ 
    if(DialogResult.OK == fgp.ShowDialog()) 
    { 
     SecureString ss = fgp.Password.ConvertToSecureString(); 
     var processInfo = new ProcessStartInfo 
     { 
      WorkingDirectory = workingDirectory, 
      FileName = "a name", 
      UserName = loggedUserName, 
      Password = ss, 
      Domain = userNameDomain, 
      UseShellExecute = false, 
     }; 
     Process.Start(processInfo); 
    } 
} 
0

我使用Windows密碼存儲來管理此類密碼。查看包裝windows API的http://credentialmanagement.codeplex.com/庫。您的Setup-Routine或Admin可以將密碼添加到商店,然後可以從應用程序在運行時檢索該密碼。唯一的缺點是商店是用戶特定的。您無法創建可供多個用戶使用的密碼。

它是如此簡單:

 _credentials = new CredentialSet("myApp:*"); 
     if (_credentials.Count == 0) 
     { 
      //TODO: ask user for password, supply it here, or use windows UI to set password (rundll32.exe keymgr.dll, KRShowKeyMgr) 
      var c = new Credential() 
      { 
       Target = "myApp:Production", 
       Username = "SomeUser", 
       Description = "Credentials for doing something...", 
       PersistanceType = PersistanceType.LocalComputer, 
       Type = CredentialType.DomainPassword 
      }; 
      c.Save(); 
      _credentials.Add(c); 
     }