Password Hashing - Why salt 60,000 times

瘦欲@ 提交于 2019-12-10 06:31:37

问题


I'm working for a Fortune 100 company and I'm thrown into being tasked with security moving from SHA1 to SHA-2 . This is not my area of expertise, but as I study cryptography I am questioning the outdated information etc...

  1. SHA-2 is obviously needed over SHA-1 but when the security team KNOWS that the hashing of password + salt is using SHA, with GPU being so ridiculously fast at cracking billions of hashes - I do not get why for passwords i'm not being told to use bcrypt or another equivalent that is slow , WHY?

  2. I'm shown a powerpoint slide in which i'm told to create my salt 60,000 times. I searched all over the internet and I'm not seeing any such advise or examples. Why?

I'm using C#

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

I suppose that I'm not told to create a salt over and over, but to create the hash over and over.

Would this logic be appropriate?

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

How do I make this hashing to work properly?

Update found the powerpoint slide

Update with Code - Problem with implementation on verification of the hash

Problem is when I use the check on the code I'm trying if (resultHash.Equals(hassPassword)) and it does not match...

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

NEW Question figured that I would go ahead and create a new question , thanks everyone in advance. Verification of Hashing password is not working


回答1:


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

I'm guessing this is why they're asking you to hash 60000 time. To add a work factor and slow down brute force attacks.

How do I make this hashing to work properly?

Something like this:

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



回答2:


To me this looks like an attempt to reimplement a PBKDF2 algorithm, to get a cost factor.

Usually it is not recommended to make experiments with security functions, instead one should use a proven well tested algorithm. Your concern about the algorithm above is justified, try to convince your team to switch to BCrypt.Net or to PBKDF2.

When you go for PBKDF2, then you can either use the built in 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.



来源:https://stackoverflow.com/questions/37342435/password-hashing-why-salt-60-000-times

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!