.NET中的密码加密/解密代码

kar*_*art 27 .net c# encryption cryptography

我希望在C#中简单加密和解密密码.如何在数据库中以加密格式保存密码并通过解密检索原始格式?

thi*_*eek 16

干得好.我发现它在互联网上的某个地方.对我来说效果很好.

    /// <summary>
    /// Encrypts a given password and returns the encrypted data
    /// as a base64 string.
    /// </summary>
    /// <param name="plainText">An unencrypted string that needs
    /// to be secured.</param>
    /// <returns>A base64 encoded string that represents the encrypted
    /// binary data.
    /// </returns>
    /// <remarks>This solution is not really secure as we are
    /// keeping strings in memory. If runtime protection is essential,
    /// <see cref="SecureString"/> should be used.</remarks>
    /// <exception cref="ArgumentNullException">If <paramref name="plainText"/>
    /// is a null reference.</exception>
    public string Encrypt(string plainText)
    {
        if (plainText == null) throw new ArgumentNullException("plainText");

        //encrypt data
        var data = Encoding.Unicode.GetBytes(plainText);
        byte[] encrypted = ProtectedData.Protect(data, null, Scope);

        //return as base64 string
        return Convert.ToBase64String(encrypted);
    }

    /// <summary>
    /// Decrypts a given string.
    /// </summary>
    /// <param name="cipher">A base64 encoded string that was created
    /// through the <see cref="Encrypt(string)"/> or
    /// <see cref="Encrypt(SecureString)"/> extension methods.</param>
    /// <returns>The decrypted string.</returns>
    /// <remarks>Keep in mind that the decrypted string remains in memory
    /// and makes your application vulnerable per se. If runtime protection
    /// is essential, <see cref="SecureString"/> should be used.</remarks>
    /// <exception cref="ArgumentNullException">If <paramref name="cipher"/>
    /// is a null reference.</exception>
    public string Decrypt(string cipher)
    {
        if (cipher == null) throw new ArgumentNullException("cipher");

        //parse base64 string
        byte[] data = Convert.FromBase64String(cipher);

        //decrypt data
        byte[] decrypted = ProtectedData.Unprotect(data, null, Scope);
        return Encoding.Unicode.GetString(decrypted);
    }
Run Code Online (Sandbox Code Playgroud)

  • 也许我错了,但看起来这个解决方案不能跨用户/机器移植,因此不适合存储加密数据.从文档:"DPAPI将关键数据存储在用户配置文件中".如果您使用此方法加密和存储数据,则在重建服务器时,您将无法从其他计算机检索和解密数据,或者天堂禁止. (8认同)
  • 这是一个玩笑,对吧?因为它是获得大量观点的问题的公认答案,而且这是任何人都不应该做的事情. (7认同)
  • @DanFromGermany添加对System.Security程序集的引用.请参阅http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata(v=vs.110).aspx (2认同)

Cog*_*eel 11

编辑:这是一个非常古老的答案.SHA1在2011年已被弃用,现在已在实践中被破坏.https://shattered.io/改为使用更新的标准(例如SHA256,SHA512等).

如果您在我的评论中对问题的回答是"否",那么我使用的是:

    public static byte[] HashPassword(string password)
    {
        var provider = new SHA1CryptoServiceProvider();
        var encoding = new UnicodeEncoding();
        return provider.ComputeHash(encoding.GetBytes(password));
    }
Run Code Online (Sandbox Code Playgroud)

  • 不要对哈希密码使用快速哈希.不是SHA-1,也不是SHA-2.使用scrypt,bcrypt或PBKDF2.这也不是问题的答案,因为OP需要可逆性. (10认同)
  • SHA1已被泄露,如下所示:http://okami-infosec.blogspot.com/2007/01/hash-sha-1-compromised.html (2认同)