Reputation: 33
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.
Upvotes: 0
Views: 1062
Reputation: 1687
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));
Upvotes: 1