5

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

enter image description here

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

Community
  • 1
  • 1
  • 4
    The loop doesn't make sense. It is basically wasting CPU time since the result will be the same for each iteration. Also, The salt must be unique for each password for it to be effective. – Nasreddine May 20 '16 at 09:05
  • Can you show me an example ? –  May 20 '16 at 09:08
  • @Nasreddine Even if it weren't the same, it would still be useless, as the salt is publicly readable. – Rob May 20 '16 at 09:09
  • 6
    Yeah, the point is that you are supposed to take the resulting hash each time + salt and rehash. The idea is that by doing so you negate rainbow tables, and slow down the process of doing a check for a matching password. – gview May 20 '16 at 09:09
  • @MillRunner I would advise asking the author of that powerpoint slide. Either they've worded it in a strange way (and they mean something else), or they don't really know how salting works. Either way, I'd ask for clarification. – Rob May 20 '16 at 09:09
  • Sounds like someone is confused. Its good to have a slow hashing function but that should be because the algorithm is expensive, not because you are wasting CPU cycles. The hash result will still be simple to brute force. – Jodrell May 20 '16 at 09:10
  • @gview This sounds plausible, but the fact they wrote 'create a salt 60000' rather than 'salt 60000 times' is a bit strange – Rob May 20 '16 at 09:11
  • @Rob The salt is not supposed to be a secret. The point of the salt, as gview mentioned, is make rainbow tables ineffective. – Nasreddine May 20 '16 at 09:11
  • @Nasreddine I know that. My point being, wasting time on creating salts is useless, as the attacker has immediate access to it anyway. – Rob May 20 '16 at 09:12
  • Ok , found the powerpoint, - what is the verdict? –  May 20 '16 at 09:16
  • That is telling you to re salt and hash the hashed version 60000 time (on my reading), ie hash(hash(hash(....hash(pwd+salt) + salt) + salt) – tolanj May 20 '16 at 09:19
  • So is this a good way to do this , looks like they are using the same salt ! right? –  May 20 '16 at 09:22
  • The best would be to ask the security team, don't you think? – Thomas Ayoub May 20 '16 at 09:24
  • See this thread http://stackoverflow.com/questions/348109/is-double-hashing-a-password-less-secure-than-just-hashing-it-once – tolanj May 20 '16 at 09:27
  • It looks like it only wants to hash 60.000 times, not create a new salt. Basically you have made a slow hasher, to slow down bruteforce attempts even further. – Lasse V. Karlsen May 20 '16 at 12:44
  • You aren't being told to use bcrypt because your security team is stupid. **You should use bcrypt**! Or, better yet, scrypt. – SLaks May 20 '16 at 19:26

2 Answers2

9

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)));
    }
}
Nasreddine
  • 36,610
  • 17
  • 75
  • 94
  • that is what the slide suggests. – Jodrell May 20 '16 at 09:36
  • Well, i'm having trouble getting this to properly verify /validate like I normally been doing. I probably need to create a new question, but I will at first post my code above in the question etc.. –  May 20 '16 at 18:26
  • New question based on your code and mine http://stackoverflow.com/questions/37354199/verification-of-hashing-password-is-not-working-complete-code-shown –  May 20 '16 at 19:11
  • @MillRunner I'm trying to write a complete answer. – Nasreddine May 20 '16 at 19:13
  • @Nasreddine -- thanks so much , the question i posted is getting a lot of feedback ( new question ) your code i'm sure is fine.... i'm not smart enough to write the proper code to validate/verify it . thanks so much in advance –  May 20 '16 at 19:31
4

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.

martinstoeckli
  • 23,430
  • 6
  • 56
  • 87
  • I agree, but at the company I'm at, sadly they don't want PBKDF2 or BCrypt - It is a battle I can't win... I know now that whenever I am allowed to I will implement the better ones. –  May 20 '16 at 18:50
  • I'm having trouble with that code and verify .. :/ ( OP ) –  May 20 '16 at 18:50