5

I am quite new to cryptography and want to get my head around hashing algorithms.

I have sources the following to create a hashed version of a password, which can be stored in my database.

    public static string hashPasswordGenerator(string password)
    {
        System.Security.Cryptography.SHA256Managed crypt = new System.Security.Cryptography.SHA256Managed();
        StringBuilder hash = new StringBuilder();
        byte[] cry = crypt.ComputeHash(Encoding.UTF8.GetBytes(password), 0, Encoding.UTF8.GetByteCount(password));
        return Convert.ToBase64String(cry);
    }

My example user is User1 with password Password1, this returns a hashed version of GVE/3J2k+3KkoF62aRdUjTyQ/5TVQZ4fI2PuqJ3+4d0=

My questions are:

  1. Is this secure?
  2. Should I add a salt to this? If so can someone show me a simple example as I do not really understand how the salt it generated so that it will match the password every time?
  3. If someone has this hashPasswordGenerator method could they reverse engineer my password?

Thanks in advance.

user3284707
  • 3,033
  • 3
  • 35
  • 69
  • In your example `StringBuilder hash = new StringBuilder();` is never used. – Ashigore May 28 '16 at 12:43
  • Possible duplicate of [Is SHA-1 secure for password storage?](http://stackoverflow.com/questions/2772014/is-sha-1-secure-for-password-storage) (SHA-256 and SHA-1 are not fundamentally different) – Artjom B. May 28 '16 at 13:21
  • You should never use a simple hashing function for hashing passwords. You need to use an intentionally slow hashing function like PBKDF2, bcrypt, scrypt and Argon2. See more: [How to securely hash passwords?](http://security.stackexchange.com/q/211/45523) – Artjom B. May 28 '16 at 13:22

2 Answers2

5

Is this secure?

Not really if you're just using SHA2 without a salt. (not saying the SHA2 can be reversed easily)

Should I add a salt to this?

Yes.

If so can someone show me a simple example

Use RNGCryptoServiceProvider:

RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
var salt = new byte[32];
rngCsp.GetBytes(salt); // this will fill the buffer with random values

as I do not really understand how the salt it generated so that it will match the password every time

You must save the salt (which must be unique for each password) along with the hashed(password+salt).

If someone has this hashPasswordGenerator method could they reverse engineer my password?

Yes if it's a dictionary password and if you're not using salts. Otherwise no (for the foreseeable future) since hashes are supposed to be hard to reverse.

BTW instead of trying to reinvent the wheel you should look into using PBKDF2 for your password hashing needs since it has a work factor that can slow down brute force attacks (number of iteration).

Nasreddine
  • 36,610
  • 17
  • 75
  • 94
  • 1
    Thanks very much for your answer. Ok great so the salt how should I store this, in a separate field, or in the same field. The example on PBLDF2 has `Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash)` so is this a pipe delimited string? – user3284707 May 28 '16 at 13:37
  • You can store it in a separate field since it'll be easier to read back without having to parse a string. – Nasreddine May 28 '16 at 13:40
  • So is this salt value added to the password before it is hashed meaning that two passwords which are the same are never the same hashed? So to check the password when it comes in, I look up the salt, add to the plain text password, then hash and see if they match? – user3284707 May 28 '16 at 13:45
  • Yes. That's about it. – Nasreddine May 28 '16 at 13:47
2

Is this secure?

Yes it is, and no it's not. The question should be "Is this secure enough for my requirements?", which is something only you can answer.

Should I add a salt to this?

Yes you should.

If someone has this hashPasswordGenerator method could they reverse engineer my password?

No they couldn't. At worst it will point them in the right direction for brute-forcing.

The problem with your solution as it stands is that it's much too easy to hack.

The first problem is obviously the lack of a salt value which means if 2 users have the same password they will have the same hash, which makes it easier to compromise multiple accounts.

Secondly, SHA256 is MUCH too quick to be any good at making secure password hashes. You should use bcrypt or similar where you can control the number of rounds in order to make hash generation "slow". The reason you want it to be slow is because your application only needs to generate one hash at a time so its no big deal if computationally it takes 10000 times as long to generate a has than it does with SHA256, but a hacker needs to generate billions of hashes. So making this take 10000 times longer for him is a huge deal.

Ashigore
  • 4,618
  • 1
  • 19
  • 39
  • Thanks very much for your answer, I have taken a look at PBKDF2 as suggested to add the iterations. I am still confused about salt though. If the user can get hold of the password can they also not get hold of the salt? – user3284707 May 28 '16 at 13:39
  • @user3284707 Yes, but it'll slow down a brute force attack considerably. – Nasreddine May 28 '16 at 13:48
  • @user3284707 This wikipedia article has more details on the [how](https://en.wikipedia.org/wiki/Salt_(cryptography)) (the explanation can't fit in a stack overflow comment). – Nasreddine May 28 '16 at 13:49