【问题标题】:Store password securely and retrieve it later安全存储密码并稍后检索
【发布时间】:2015-06-12 09:15:10
【问题描述】:

用例:在无人值守模式下运行安装程序。

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

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

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

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

【问题讨论】:

  • 听起来您没有太多选择,只要您正确加密它 - 这是困难的部分。另请注意,命令行上的密码在任务管理器中是可见的。
  • @vcsjones 是的。我知道密码将在任务管理器中可见。我希望有一种 SecureString 方式来执行此操作。

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


【解决方案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
}

加密是使用本地机器密钥完成的,因此只有同一台机器可以解密密码

将 Secure 字符串转换为 InSecure:

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

将 InSecure 字符串转换为安全字符串:

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
相关资源
最近更新 更多