密码哈希 - 为什么要盐60,000次

时间:2016-05-20 09:02:30

标签: c# hash sha256 sha

我正在为一家财富100强公司工作,而我正在承担从SHA1到SHA-2的安全任务。这不是我的专业领域,但在我研究密码学时,我质疑过时的信息等......

  1. 显然需要SHA-2而不是SHA-1,但是当安全团队知道密码+盐的散列使用SHA时,GPU在破解数十亿个哈希时非常快速 - 我不明白为什么对于密码,我没有被告知使用bcrypt或其他慢速的等价物,为什么?

  2. 我展示了一张幻灯片幻灯片,其中告诉我创建我的盐60,000次。我在互联网上搜索过,我没有看到任何这样的建议或例子。为什么呢?

  3. 我正在使用C#

    string SaltAndPwd = string.Concat(plainTextPassword, salt);
    SHA256 sha2 = SHA256Managed.Create();
    byte[] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd));
    

    我想我没有被告知反复创建一个盐,而是一遍又一遍地创建哈希。

    这种逻辑是否合适?

    string plainTextPassword = "aF7Cvs+QzZKM=4!";  
    string salt = "o9kc5FvhWQU==";
    SHA256 sha2 = SHA256Managed.Create();
    
    for(var i = 0; i <= 60000; i++)
    {
       byte[] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd));
    }
    

    如何使此散列正常工作?

    更新找到了powerpoint幻灯片

    enter image description here

    使用代码进行更新 - 验证哈希值时实施的问题

    问题是当我使用我正在尝试的代码检查时 if (resultHash.Equals(hassPassword))并且它不匹配......

        public string BuildVerify()
        {
    
            string password = "";
            string salt = "";
            byte[] result;
    
    
            using (var sha256 = SHA256.Create())
            {
                password = "hovercraft";
    
                // step 1: you can use RNGCryptoServiceProvider for something worth using
                var passwordHashing = new PasswordHashing();
                salt = passwordHashing.CreateRandomSalt();
    
                // step 2
                string hash =
                   Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + password)));
    
                // step 3
                result = sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + hash));
    
                // step 4
                for (int i = 0; i < 60000; i++)
                {
                    result =
                     sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + Convert.ToBase64String(result)));
                }
            }
    
    
            // TESTING  VERIFY this works ..
    
            string SaltAndPwd = string.Concat(password, salt);
            SHA256 sha2 = SHA256Managed.Create();
            byte[] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd));
            string resultHash = Convert.ToBase64String(buff);
            string hassPassword = Convert.ToBase64String(result);
    
            if (resultHash.Equals(hassPassword))
            {
                // perfect 
            }
    
    
    
    
            return "";
    
        }
    
    
    public class PasswordHashing
    {
    
        public string CreateRandomSalt()
        {
            string password = "";
            password = HashPassword.CreateSalt(8) + "=";
            password = password.Replace("/", "c");
            return password;
        }
    
    }
    

    ///

        public static string CreateSalt(int size)
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    
            byte[] buff = new byte[size];
            rng.GetBytes(buff);
            return Convert.ToBase64String(buff);
        }
    

    新问题   我想我会继续创建一个新问题,提前感谢大家。 Verification of Hashing password is not working

3 个答案:

答案 0 :(得分:9)

  

我不明白为什么密码我没有被告知要使用bcrypt或其他慢速的等价物

我猜这就是他们要求你哈希60000次的原因。添加工作因素并减缓暴力攻击。

  

如何使此散列正常工作?

这样的事情:

using (var sha256 = SHA256.Create())
{
    string password = "hovercraft";

    // step 1: you can use RNGCryptoServiceProvider for something worth using
    string salt = GenerateSalt();

    // step 2
    string hash = 
       Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + password)));

    // step 3
    byte[] result = sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + hash));

    // step 4
    for (int i = 0; i < 60000; i++)
    {
        result = 
         sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + Convert.ToBase64String(result)));
    }
}

答案 1 :(得分:4)

对我而言,这似乎是尝试重新实现PBKDF2算法,以获得成本因素。

通常不建议使用安全功能进行实验,而应使用经过验证的经过验证的算法。您对上述算法的关注是合理的,请尝试说服您的团队切换到BCrypt.Net或PBKDF2。

当您选择PBKDF2时,您可以使用内置的dotnet类Rfc2898DeriveBytes来计算带有HMACSHA1的PBKDF2(即使在今天也是标准),或者您可以使用支持其他哈希函数的实现比如PBKDF2 with SHA-256

答案 2 :(得分:0)

如果你这样做了,

using System;
using System.Security.Cryptography;

...

private static byte[] SaltForUser(User user)
{
    // Its important that each hash value that is stored uses a different salt.
}

...

public static byte[] StrongHash(User user, string password)
{
    var deriver = new Rfc2898DeriveBytes(password, SaltForUser(user), 2);
    using (var hash = SHA256Managed.Create())
    {
        return hash.ComputeHash(deriver.GetBytes(4096));
    }
}

然后您将使用60000次迭代。