2

I'm working on upgrading the password hashing function in a legacy asp.net application.

It was using Rfc2898DeriveBytes with the default SHA1. I've upgraded the application now to .Net 4.7.2, so I'm now able to choose a better hashing algorithm.

This is my function so far...

public static string GeneratePasswordHash(string password)
{
    var private_key = "{my-secret-key}";

    using (var derived_bytes = new Rfc2898DeriveBytes(password + private_key, 32, 10000, HashAlgorithmName.SHA384))
    {
        byte[] hash = derived_bytes.GetBytes(64);
        byte[] salt = derived_bytes.Salt;

        byte[] combined_hash = new byte[96];

        System.Buffer.BlockCopy(salt, 0, combined_hash, 0, 32);
        System.Buffer.BlockCopy(hash, 0, combined_hash, 32, 64);

        return Convert.ToBase64String(combined_hash);
    }
}

I'm not sure how to go about choosing an appropriate key and salt size though. At the moment I've picked 32 and 64 bytes respectively, but these were really just chosen arbitrarily. I know the minimum salt size is 8 bytes, but I don't really know why I would choose a larger vs smaller salt.

Also is there some kind of rule-of-thumb to decide the ratio between salt and key size?

Performance is not really a consideration, as it will never be running frequently enough to put any noticeable load on the server.

Likewise storage space for the hash is fairly much irrelevant. Whether the hashed passwords require 88 characters or 128, makes no real difference.

Previously salt and key size were both 32 bytes. If I were to keep it the same, does this somehow negate the benefit of changing to SHA384, since my final hash will be the same size as before?

With my very basic understanding of hashing algorithms, bigger numbers = better security. However I don't want to choose rediculously large key sizes etc. if doing so is completely pointless from a security perspective.

user1751825
  • 4,029
  • 1
  • 28
  • 58
  • When you're switching already. Maybe you should switch to something like bcrypt or scrpyt (you should read about). The longer the algorithm needs and the more iterations are used the more secure it is. https://crackstation.net/hashing-security.htm – user743414 Oct 20 '20 at 11:58
  • 1
    Rfc2898DeriveBytes is part of the standard System.Security.Cryptography library. As far as I can see, the others would require 3rd party nuget packages. Unless there is some very compelling reason, I would always prefer to stick with what's already included with the standard libraries. The only complaints that I've found about Rfc2898DeriveBytes relate to the use of the old SHA1 hashing algorithm, but it now supports all of the other hashing algorithms as well. – user1751825 Oct 20 '20 at 12:13
  • Go Bcrypt. Good info [here](http://www.foursails.co/blog/bcrypt/). (Sry, you posted while i was writing.) – wazz Oct 20 '20 at 12:17
  • Haven't read what Rfc2898DerviceBytes does. Looks like it's some PBKDIF2 implementation. So maybe this helps you to take a decision: https://security.stackexchange.com/questions/220732/how-to-configure-nets-pbkdf2-implementation-rfc2898derivebytes-in-2019 – user743414 Oct 20 '20 at 12:18

0 Answers0