0

Use case: To run installer in unattended mode.

How: To achieve this I am using Process.Start and passing it ProcessStartInfo as below:

 var processStartInfo = new ProcessStartInfo
 {
       FileName = installerPath,
       Arguments = commandLineArguments
 };

Issue: One of the parameters in the command line arguments is username and password. The username and password are provided by an API. What I am doing is saving encrypted password in database and then return it through the API. Then on the receiving end decrypting it. I know its not a best practice to save encrypted passwords (instead should save hash of the password) but pls. see the use case mentioned above.

I would like to know if saving encrypted password (and decrypting it later) is the best way to go here or is there a better way.

souser
  • 33
  • 1
  • 8
  • Doesn't sound like you have much of a choice, as long as you encrypt it properly - which is the hard part. Also beware that a password on the command line is visible in the Task Manager. – vcsjones Apr 07 '15 at 17:16
  • @vcsjones Yeah. I know that the password will be visible in the task manager.. I wish there was a SecureString way of doing this. – souser Apr 07 '15 at 17:25

1 Answers1

1

For encryption I'm using this class :

/// <summary>
/// Encrypt Password with local key
/// </summary>
public class SecureIt
{
    #region Declaration

    static byte[] entropy = System.Text.Encoding.Unicode.GetBytes("Salt Is Not A Password");

    #endregion

    #region Methods

    public static string EncryptString(System.Security.SecureString input)
    {
        byte[] encryptedData = System.Security.Cryptography.ProtectedData.Protect(
            System.Text.Encoding.Unicode.GetBytes(ToInsecureString(input)),
            entropy,
            System.Security.Cryptography.DataProtectionScope.CurrentUser);
        return Convert.ToBase64String(encryptedData);
    }

    public static SecureString DecryptString(string encryptedData)
    {
        try
        {
            byte[] decryptedData = System.Security.Cryptography.ProtectedData.Unprotect(
                Convert.FromBase64String(encryptedData),
                entropy,
                System.Security.Cryptography.DataProtectionScope.CurrentUser);
            return ToSecureString(System.Text.Encoding.Unicode.GetString(decryptedData));
        }
        catch
        {
            return new SecureString();
        }
    }

    public static SecureString ToSecureString(string input)
    {
        SecureString secure = new SecureString();
        foreach (char c in input)
        {
            secure.AppendChar(c);
        }

        secure.MakeReadOnly();
        return secure;
    }

    public static string ToInsecureString(SecureString input)
    {
        string returnValue = string.Empty;
        IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(input);
        try
        {
            returnValue = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr);
        }
        finally
        {
            System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
        }

        return returnValue;
    }

    #endregion
}

The encryption is done with a the Local Machine key so only the same machine can Decrypt the password

Convert Secure string to InSecure:

SecureIt.ToInsecureString(SecureIt.DecryptString(this._password));

Convert InSecure String to Secure:

SecureIt.EncryptString(SecureIt.ToSecureString(connection.Password));
C1rdec
  • 1,647
  • 1
  • 21
  • 46
  • Same machine thing will not work for me. I might go with this one http://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp/10177020#10177020 – souser Apr 07 '15 at 17:54