安全存储密码并在以后检索

时间:2015-04-07 17:13:47

标签: c# .net security passwords .net-4.5

用例:以无人参与模式运行安装程序。

如何: 为了实现这一点,我使用Process.Start并将其传递给ProcessStartInfo,如下所示:

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

问题:命令行参数中的一个参数是用户名密码。用户名和密码由API提供。我正在做的是将加密密码保存在数据库中,然后通过API返回。然后在接收端解密它。我知道保存加密密码不是最好的做法(而应该保存密码的哈希),但请等一下。看看上面提到的用例。

我想知道保存加密密码(以及稍后解密)是最好的方式,还是有更好的方法。

1 个答案:

答案 0 :(得分:1)

对于加密我正在使用这个类:

/// <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
}

使用本地计算机密钥进行加密,因此只有同一台计算机才能解密密码

将安全字符串转换为InSecure:

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

将InSecure String转换为Secure:

SecureIt.EncryptString(SecureIt.ToSecureString(connection.Password));