Hash and salt passwords in C#

后端 未结 14 1842
野趣味
野趣味 2020-11-22 04:00

I was just going through one of DavidHayden\'s articles on Hashing User Passwords.

Really I can\'t get what he is trying to achieve.

Here is his code:

<
14条回答
  •  死守一世寂寞
    2020-11-22 04:12

    I read all answers and I think those enough, specially @Michael articles with slow hashing and @CodesInChaos good comments, but I decided to share my code snippet for hashing/validating that may be useful and it does not require [Microsoft.AspNet.Cryptography.KeyDerivation].

        private static bool SlowEquals(byte[] a, byte[] b)
                {
                    uint diff = (uint)a.Length ^ (uint)b.Length;
                    for (int i = 0; i < a.Length && i < b.Length; i++)
                        diff |= (uint)(a[i] ^ b[i]);
                    return diff == 0;
                }
    
        private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes)
                {
                    Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt);
                    pbkdf2.IterationCount = iterations;
                    return pbkdf2.GetBytes(outputBytes);
                }
    
        private static string CreateHash(string value, int salt_bytes, int hash_bytes, int pbkdf2_iterations)
                {
                    // Generate a random salt
                    RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
                    byte[] salt = new byte[salt_bytes];
                    csprng.GetBytes(salt);
    
                    // Hash the value and encode the parameters
                    byte[] hash = PBKDF2(value, salt, pbkdf2_iterations, hash_bytes);
    
                    //You need to return the salt value too for the validation process
                    return Convert.ToBase64String(hash) + ":" + 
                           Convert.ToBase64String(hash);
                }
    
        private static bool ValidateHash(string pureVal, string saltVal, string hashVal, int pbkdf2_iterations)
                {
                    try
                    {
                        byte[] salt = Convert.FromBase64String(saltVal);
                        byte[] hash = Convert.FromBase64String(hashVal);
    
                        byte[] testHash = PBKDF2(pureVal, salt, pbkdf2_iterations, hash.Length);
                        return SlowEquals(hash, testHash);
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
    

    Please pay attention SlowEquals function that is so important, Finally, I hope this help and Please don't hesitate to advise me about better approaches.

提交回复
热议问题