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

Password Hashing - Why salt 60,000 times

我在一家财富 100 强公司工作,我的任务是将安全性从 SHA1 转移到 SHA-2。这不是我的专业领域,但在我学习密码学的过程中,我正在质疑过时的信息等...

  1. SHA-2 显然比 SHA-1 更需要,但是当安全团队知道密码 + salt 的散列使用的是 SHA,GPU 在破解数十亿散列时速度快得离谱 - 我不明白为什么我没有被告知使用 bcrypt 或其他速度慢的等效密码,为什么?

  2. 我看到了一张 powerpoint 幻灯片,其中告诉我制作 60,000 次盐。我在整个互联网上进行了搜索,但没有看到任何此类建议或示例。为什么?

我正在使用 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 幻灯片

更新代码 - 哈希验证的实施问题

问题是当我对正在尝试的代码使用检查时 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);
    }

新问题 我想我会继续提出一个新问题,在此先感谢大家。

I do not get why for passwords i'm not being told to use bcrypt or another equivalent that is slow

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

How do I make this hashing to work properly?

像这样:

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)));
    }
}

对我来说,这看起来像是尝试重新实现 PBKDF2 算法,以获得成本因素。

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

当你选择 PBKDF2 时,你可以使用内置的 dotnet class Rfc2898DeriveBytes to calculate a PBKDF2 with HMACSHA1 (which is the standard even today), or you can use an implementation which supports other hash functions like PBKDF2 with SHA-256.