3
$\begingroup$

Background

I have recently started to get into web development and thus I have been creating databases for users.

After some research, I discovered that password encryption is not password hashing.
My next spell of learning was that I needed to add salts to my passwords to make them harder to crack.
For this I implemented a hard-coded salt to the start of all my passwords; I later learned that actually the salts should all be different, otherwise they are just peppers.

Storing data

I created a table in my database that stores the passwords and the salts (maybe a question for a different day, but I am not sure where to store the salts).

The passwords are hashed using MD5 and then stored. (There is not really a reason as to why I chose MD5 and if it is better to use another one then I will.)

I currently use a PRNG to create the salt upon registration to the site. The salts are not hashed and are simply just stored in a separate field to the password.

Question(s)

What is a good salt?

Assuming someone gains access to the databases. They would see a series of MD5 hashes and then a series of random numbers and letters (8 bytes currently).

I understand that the question may appear open-ended.
Would I need to hash my salts (that sounds weird to me), create longer salts, or do something else?

$\endgroup$
  • 2
    $\begingroup$ Your next step should I believe be learning that password hashing must not be implemented with a fast cryptographic hash like MD5 (which BTW is widely considered as unsuitable for any new application). An entropy stretching slow hash is required. That's far more important than using a good salt or pepper. $\endgroup$ – fgrieu Mar 23 '17 at 12:25
  • $\begingroup$ @fgrieu is SHA256 more acceptable? $\endgroup$ – JustCarty Mar 23 '17 at 12:53
  • 5
    $\begingroup$ SHA-256 is fine for efficient hashing (of e.g. files), not as an entropy stretching slow hash. The absolute baseline for that is PBKDF2 (with HMAC and a hash, like SHA-256) and an appropriately large iteration count . More secure/recent choices are (from time-proven to experimental) bcrypt, scrypt, argon2 and balloon. $\endgroup$ – fgrieu Mar 23 '17 at 13:49
  • 1
    $\begingroup$ Do not use MD5. Use a password hashing algorithm, which is not the same thing as an ordinary cryptographic hash algorithm. Use one of the functions mentioned by fgrieu; read How to securely hash passwords? for more details. $\endgroup$ – Gilles Mar 23 '17 at 22:55
3
$\begingroup$

If you are using random numbers and letters (upper and lower case) for salts, you can make the assumption that each character has 5.9 bits of entropy, assuming they are actually random.

A salt needs to be unique enough never to be used by 2 users that happen to have the same password. Rather than calculate some value on how likely that is, it is better to just assume that every password entry in the database should have a unique salt. It is even better that EVERY salt used for password hashing on every system on earth be unique.

Lets assume that 8 billion people all have a password for something. I have about 100 passwords for various systems, we can round to 33 bits of uniqueness for people, and 7 bits for password count.

Thus you want a bare minimum of 40 bits of uniqueness, which requires an 80-bit salt. The current trend is to simply use a 128-bit random number, making the chance of a salt collision "cryptographically unlikely" for the near term. 80 bits would require random 14 alphanumeric characters. 128 bits requires 22 characters.

There are generally standard methods on combining the salt and hashed password into a single string, I would suggest using that format. And of course, there will be mentions that a cryptographic hash is unsuitable for passwords and you need a memory/compute hard Password Based Key Derivation Function or a Password Hashing Scheme, which is true; read How to securely hash passwords? or one many posts on this site on how to properly choose and utilize one of these. MD5 is not even close to suitable for this, or any secure system.

$\endgroup$
  • $\begingroup$ Based on @fgrieu comment, I have learnt that MD5 is bad. I know I said my salt was letters and numbers, but is it a good idea to have a salt that uses a wide variety of characters? $\endgroup$ – JustCarty Mar 23 '17 at 19:39
  • 1
    $\begingroup$ @Carty: The amount of entropy ("uniqueness") in a string (your salt) with $n$ characters each chosen independently and uniformly at random among $m$ is $n\log_2(m)$ bit; for example, restricting to 10 uppercase letters and digits, 51.7 bit; or 59.5 bit if we add uppercase. Thus the largest the choice of characters, the better. Note: a common practice is to use as salt a server-unique string (its name) and username. That's often considered good enough. Again, what matters most is the Password Based Key Derivation Function or Password Hashing Scheme, and its parametrization. $\endgroup$ – fgrieu Mar 24 '17 at 8:23
  • 1
    $\begingroup$ I agree that storing salt and hashed password in the standard format is a good thing, and I suggest adding a link to the that standard Modular Crypt Format. $\endgroup$ – David Cary Mar 24 '17 at 15:35
  • $\begingroup$ @fgrieu I was under the impression that the salt should be unpredictable like a CBC IV, as knowing that format would allow a rainbow table to be built prior to the user creating an account, assuming the attacker knows the username they are likely to choose $\endgroup$ – Richie Frame Mar 24 '17 at 17:29
  • $\begingroup$ @Richie Frame: Yes, random salt is king; and with predictable salt, a resourceful attacker could spend most of its computational effort before getting hold of the database of salts, usernames and hashed passwords (which is supposed to be kept secret as a first line fo defense). Notice however that the attack effort is unchanged compared to random salt. Further, with a slightly-less-poor's man salt made by concatenating a secret server-unique string stored in a single field of the database, and username, has most of the advantages of random salt. $\endgroup$ – fgrieu Mar 24 '17 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.