Hash and salt passwords in C#

后端 未结 14 1848
野趣味
野趣味 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:34

    If you dont use asp.net or .net core there is also an easy way in >= .Net Standard 2.0 projects.

    First you can set the desired size of the hash, salt and iteration number which is related to the duration of the hash generation:

    private const int SaltSize = 32;
    private const int HashSize = 32;
    private const int IterationCount = 10000;
    

    To generare the password hash and salt you can use something like this:

    public static string GeneratePasswordHash(string password, out string salt)
    {
        using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, SaltSize))
        {
            rfc2898DeriveBytes.IterationCount = IterationCount;
            byte[] hashData = rfc2898DeriveBytes.GetBytes(HashSize);
            byte[] saltData = rfc2898DeriveBytes.Salt;
            salt = Convert.ToBase64String(saltData);
            return Convert.ToBase64String(hashData);
        }
    }
    

    To verify if the password which the user entered is valid you can check with the values in your database:

    public static bool VerifyPassword(string password, string passwordHash, string salt)
    {
        using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, SaltSize))
        {
            rfc2898DeriveBytes.IterationCount = IterationCount;
            rfc2898DeriveBytes.Salt = Convert.FromBase64String(salt);
            byte[] hashData = rfc2898DeriveBytes.GetBytes(HashSize);
            return Convert.ToBase64String(hashData) == passwordHash;
        }
    }
    

    The following unit test shows the usage:

    string password = "MySecret";
    
    string passwordHash = PasswordHasher.GeneratePasswordHash(password, out string salt);
    
    Assert.True(PasswordHasher.VerifyPassword(password, passwordHash, salt));
    Assert.False(PasswordHasher.VerifyPassword(password.ToUpper(), passwordHash, salt));
    

    Microsoft Rfc2898DeriveBytes Source

提交回复
热议问题