0

In my application I have a class that hashes passwords and generates salts. For some reason every hash seems to always end with a double equals sign (==).

Am I doing something wrong? Are these hashes not secure?

The application is in c# and asp.net and the code to generate the salts and hashes is as follows...

public class PasswordService : IPasswordService
{
    private static RandomNumberGenerator random = RandomNumberGenerator.Create();

    public string HashPassword(string salt, string password)
    {
        Rfc2898DeriveBytes hasher = new Rfc2898DeriveBytes(password, Convert.FromBase64String(salt), 10000);

        byte[] hash = hasher.GetBytes(64);

        return Convert.ToBase64String(hash);
    }

    public bool VerifyPasswordHash(string salt, string password, string hash)
    {
        return HashPassword(salt, password) == hash;
    }

    public string GenerateSalt()
    {
        int max_length = 32;

        byte[] salt = new byte[max_length];

        random.GetBytes(salt);

        return Convert.ToBase64String(salt); 
    }
}

Thank you!

Dabloons
  • 1,462
  • 2
  • 17
  • 30
  • 1
    There's nothing wrong with the hash. The last step is converting it to a [Base64](https://en.wikipedia.org/wiki/Base64) string. The next problem you're going to have is transmitting those strings over the wire. You'll need to transform to ["base64url"](https://en.wikipedia.org/wiki/Base64#Variants_summary_table), by converting "+" to "-" and "/" to "_". See https://en.wikipedia.org/wiki/Base64#URL_applications for more info. – Jim Mischel Oct 31 '16 at 23:22
  • Possible duplicate of [Why does a base64 encoded string have an = sign at the end](http://stackoverflow.com/questions/6916805/why-does-a-base64-encoded-string-have-an-sign-at-the-end) – 1615903 Nov 03 '16 at 06:22

1 Answers1

2

Of course its going to end with ==, you are encoding to Base64! :). Everything in Base64 ends with ==.

SledgeHammer
  • 7,338
  • 6
  • 41
  • 86
  • 4
    This is not quite correct. There are as many `=` as necessary to fill a block. (4 base 64 characters / 3 bytes)(i.e. zero, one or two `=`) – Tibrogargan Oct 31 '16 at 22:43
  • So this isn't an error in my implementation but an artifact of my string conversion? I don't understand. C# stores strings as 16bit UTF8. Is that not evenly divisible? I think there is something I'm not understanding here. – Dabloons Oct 31 '16 at 22:49
  • What we are saying (and @Tibrogargan corrected the answer slightly) is with Base64, you will get padded with ='s to fill to the block. So you can end with 0, 1 or 2 ='s at the end of your Base64 string. That is normal. – SledgeHammer Oct 31 '16 at 22:52
  • @Dabloons - Strings being stored as UTF-16 are completely beside the point here. First, your Base64 encoder isn't taking a string, it's taking a raw sequence of bytes. Second, Base64 transforms 3 bytes of input into 4 characters of output. Your input is always 64 bytes, so that always ends up being 21 blocks for the first 63 characters, and 1 byte left over. Hence why you get two == at the end, since it padded 2 bytes to make the 22nd block. – PMV Nov 01 '16 at 01:29