2013-07-28 2 views
6

Я знаю, что вы можете запустить процесс с заданным именем пользователя/пароль следующим образом:Запуск процесса с именем пользователя и паролем

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

Проблема я столкнулся в том, что я не хотите записать фактический пароль как часть кода, и процесс не запустится, если я оставил атрибут Password пустым ... Как я могу безопасно запустить процесс, не подвергая пароль строковой кодировке в коде?

+0

Password свойство 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 Password store для управления такими паролями. Посмотрите библиотеку http://credentialmanagement.codeplex.com/, которая обтекает API окон. Либо ваш 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); 
     } 
Смежные вопросы