【问题标题】:How to store password in encrypted format in database entered from web application?如何以加密格式将密码存储在从 Web 应用程序输入的数据库中?
【发布时间】:2012-05-22 05:02:46
【问题描述】:

在我的应用程序中有一个密码字段。当用户输入密码时,它应该加密该密码并存储到数据库中。当用户登录该应用程序时,应从数据库中获取密码并进行解密。

有可能吗??

【问题讨论】:

  • 在滚动您自己的代码之前,您可能想要查看 ASP.NET 成员资格和角色提供程序,msdn.microsoft.com/en-us/library/yh26yfzy.aspx 这是内置在框架中的,因此框架的页面控件和其他功能可以很好地与此集成
  • 您的问题没有说明您是尝试创建密码登录系统,还是只是尝试存储加密字符串以供其他用途。如果您正在寻找加密字符串以便以后解密的方法,那么我建议您在问题中根本不要提及“密码”这个词,因为这会导致很多误解。

标签: c# asp.net sql-server-2008


【解决方案1】:

您可以查看this 链接,它可以帮助您朝着正确的方向开始。

话虽如此,通常的做法是存储密码本身的哈希值,而不是密码的加密版本。哈希将允许您检查用户是否输入了正确的密码(通过将您在数据库中的哈希值与用户输入的哈希值进行比较),而无需知道实际密码是什么。

这样做的好处是它通常更简单、更安全,因为您不需要加密/解密任何值。使用散列的缺点是您永远无法用户发送他们的密码(如果您打算提供某种“忘记密码”功能),而是必须将其重置为新的,随机一个。

【讨论】:

  • 无法使用密码的哈希值登录到例如电子邮件服务器。因此,双向加密是合法的需求。
  • @Micah Epps,那么您是在谈论存储密码以在其他地方使用。目前尚不清楚这是否是原始问题所要求的。这个答案正确地描述了一种密码认证方法,而不是加密字符串存储。
【解决方案2】:

如果您不希望使用 ASP.NET 成员资格和角色提供程序,这可能对您有用:

    /// <summary>
    /// Decrypts the specified encryption key.
    /// </summary>
    /// <param name="encryptionKey">The encryption key.</param>
    /// <param name="cipherString">The cipher string.</param>
    /// <param name="useHashing">if set to <c>true</c> [use hashing].</param>
    /// <returns>
    ///  The decrypted string based on the key
    /// </returns>
    public static string Decrypt(string encryptionKey, string cipherString, bool useHashing)
    {
        byte[] keyArray;
        //get the byte code of the string

        byte[] toEncryptArray = Convert.FromBase64String(cipherString);

        System.Configuration.AppSettingsReader settingsReader =
                                            new AppSettingsReader();

        if (useHashing)
        {
            //if hashing was used get the hash code with regards to your key
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(encryptionKey));
            //release any resource held by the MD5CryptoServiceProvider

            hashmd5.Clear();
        }
        else
        {
            //if hashing was not implemented get the byte code of the key
            keyArray = UTF8Encoding.UTF8.GetBytes(encryptionKey);
        }

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes.
        //We choose ECB(Electronic code Book)

        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)
        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(
                             toEncryptArray, 0, toEncryptArray.Length);
        //Release resources held by TripleDes Encryptor
        tdes.Clear();
        //return the Clear decrypted TEXT
        return UTF8Encoding.UTF8.GetString(resultArray);
    }

    /// <summary>
    /// Encrypts the specified to encrypt.
    /// </summary>
    /// <param name="toEncrypt">To encrypt.</param>
    /// <param name="useHashing">if set to <c>true</c> [use hashing].</param>
    /// <returns>
    /// The encrypted string to be stored in the Database
    /// </returns>
    public static string Encrypt(string encryptionKey, string toEncrypt, bool useHashing)
    {
        byte[] keyArray;
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

        System.Configuration.AppSettingsReader settingsReader =
                                            new AppSettingsReader();

        //If hashing use get hashcode regards to your key
        if (useHashing)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(encryptionKey));
            //Always release the resources and flush data
            // of the Cryptographic service provide. Best Practice

            hashmd5.Clear();
        }
        else
            keyArray = UTF8Encoding.UTF8.GetBytes(encryptionKey);

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes.
        //We choose ECB(Electronic code Book)
        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)

        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateEncryptor();
        //transform the specified region of bytes array to resultArray
        byte[] resultArray =
          cTransform.TransformFinalBlock(toEncryptArray, 0,
          toEncryptArray.Length);
        //Release resources held by TripleDes Encryptor
        tdes.Clear();
        //Return the encrypted data into unreadable string format
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

使用上述两种方法,您可以在将密码字符串保存到数据库时对其进行加密,并在检索时对其进行解密。

【讨论】:

  • 变量settingsReader的作用是什么?
【解决方案3】:

您可以在 SQL SERVER 中创建 SQLCLR UDF,我使用两种主要方法以加密格式保存密码。

Pwdencryp()t 加密密码,返回加密后的字符串。这在您设置密码时使用,并且加密的密码存储在 master..syslogins 表中。

http://msdn.microsoft.com/en-us/library/dd822791(v=sql.105).aspx

Pwdcompare() 接受明文密码和加密密码,并通过对明文密码进行加密并比较两者来检查它们是否匹配。当您键入密码以登录 SQL Server 时,将调用此例程。

http://msdn.microsoft.com/en-us/library/dd822792.aspx

【讨论】:

  • Pwdencrypt() 这个名字看起来有点误导。它创建密码的哈希值而不是对其进行加密。散列和加密不一样。
【解决方案4】:

当您配置 passwordFormat="Hashed" ASP.NET password hashing and password salt 时,ASP.NET SQL Server 成员资格提供程序会为您提供此功能

但是,如果您希望自己推出自己的产品,那么您需要研究 Salted Password。例如Hash and salt passwords in C#

【讨论】:

    【解决方案5】:

    简单的方法如下:

    string hashedpassword= FormsAuthentication.HashPasswordForStoringInConfigFile("your password", "SHA1");
    

    【讨论】:

      【解决方案6】:

      获取哈希密码的最简单方法如下。 FormsAuthentication.HashPasswordForStoringInConfigFile("value of string", FormsAuthPasswordFormat.MD5.ToString());

      【讨论】:

        【解决方案7】:
         string hashedPassword = Security.HashSHA1(txtPassword.Value.Trim());
          public class Security
            {
                public static string HashSHA1(string value)
                {
                    var sha1 = System.Security.Cryptography.SHA1.Create();
                    var inputBytes = Encoding.ASCII.GetBytes(value);
                    var hash = sha1.ComputeHash(inputBytes);
        
                    var sb = new StringBuilder();
                    for (var i = 0; i < hash.Length; i++)
                    {
                        sb.Append(hash[i].ToString("X2"));
                    }
                    return sb.ToString();
                }
            }
        

        【讨论】:

        • SHA-1绝对不能用于散列密码;它还远远不够强大;这是非常有害的。 SHA-1 现已正式破解。
        猜你喜欢
        • 2011-07-15
        • 2013-10-31
        • 2016-12-25
        • 2016-01-15
        • 2014-03-07
        • 2011-04-26
        • 2011-09-21
        • 1970-01-01
        • 2020-03-20
        相关资源
        最近更新 更多