23

Possible Duplicate:
Secure hash and salt for PHP passwords

WARNING Don't use MD5 for passwords, use an alternative like bcrypt


For my passwords should I use salt like this (the salt will be unique to each user and not stored directly with the password)...

$salt = sha1(md5("coders gonna code"));
$password = md5($salt.$password);

or would it be okay if I just used:

$password = md5($password);

because if I used salt, even if the user makes up a bad password like password it won't matter because the salt (in this case) would be 145ac26ff093c6e1317f7d5fb4c9fd11c77be975 so the entry for there password would be 145ac26ff093c6e1317f7d5fb4c9fd11c77be975password which according to http://howsecureismypassword.net/ it would take 3 octodecillion years to crack.... so opinions? Or should I be even worse and go

$password = md5($salt.$password.md5($salt));

If the person has gone far enough to get the salt hash, would anything be able to stop then going futher? < More of a statement this last password


To everyone who said I should do it per user... I know, this is just an example.

FabianCook
  • 20,269
  • 16
  • 67
  • 115

6 Answers6

13

You are using the salt totally incorrectly. Salts should be unpredictable; your salt is the exact opposite of that (fixed). Since a fixed hash is of absolutely no benefit, it also seems that you are counting on the salt not being known by the attacker. This is the definition of security through obscurity, which is another bad practice.

What you should be doing is:

  1. Use an unpredictable string of reasonable length as the salt. Randomly generated 8-character strings from a pool such as lower/upper case letters and digits are fine.
  2. Use a different salt for each user, and change it every time they change their password.
  3. Move from MD5 (which is considered broken) to another hash function better suited to this application. SHA-1 is better because it's not considered broken; bcrypt is the best because it has a configurable load factor.
Jon
  • 428,835
  • 81
  • 738
  • 806
13

You should change the salt so that it is specific to each user, not a system wide constant. This will make rainbow table attacks against your password hashes much more inconvenient.

There is a good write up on the evolution of salting in this article by Troy Hunt.

Edit

$salt something unique to each password record, which adds much entropy to it. This is usually a random sequence of bytes, stored with the user account.

Hashing is traditionally done on the concatenation of salt + password.

$passwordHash = hash($salt.$password);

As others have said, don't use MD5 for hashing. It is broken.

Applying additional proprietary algorithms to password or salt prior to hashing is not recommended. Instead, look at an industry strength solution such as PBKDF2, which, in addition to salting, also requires many (typically > 10k) repeated iterations which will further slow down an attacker.

If you adopt OWASP guidelines, the number of hashes performed should be increased regularly (to counteract Moore's Law). The number of hashes should also be persisted per user, meaning you will need to store the triple of hashed password, salt, and number of iterations.

StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • Check edit. Thanks, but I know this. :) – FabianCook Oct 04 '12 at 10:15
  • 2
    I think this answers the question the best, because to me it seems that the OP don't clearly know why should he use salt with his passwords. If you use fixed salt, it doesn't matter if it would take 3 billion years, to crack the password by brute force, because the attacker will just look at your database table, see that there are 3000 password with the same hash value and guess that it mus be 'password' or '12345' or whatever. You use dynamic hashes so the hashed and slated password couldn't be guessed by statistical means. – Richard Otvos Oct 04 '12 at 10:29
9
  1. Don't use MD5 as your hashing algorithm, use something more secure such as SHA256 or even bcrypt.

  2. Definately salt the password, if someone did gain entry to your database they would not be able to reverse the passwords for common hashes or using techniques such as rainbow attacks.

http://michaelwright.me/php-password-storage

http://en.wikipedia.org/wiki/Bcrypt

Darren
  • 68,902
  • 24
  • 138
  • 144
  • 2
    Everyone think this is correct? I think so? – FabianCook Oct 04 '12 at 10:22
  • 1
    Sha256 is not very secure still tbh, here is also a working version of bcrypt done right with a byte range salt http://stackoverflow.com/questions/4795385/how-do-you-use-bcrypt-for-hashing-passwords-in-php – Sammaye Oct 04 '12 at 10:34
4

First of all you should never store md5 directly, which you regognized already. PHP 5.5 will bring new methods to easily create and verify passwords in 1 line, until then you can use https://github.com/ircmaxell/password_compat (forward-compatible) to generate & verify safe password hashes.

Martin Müller
  • 2,565
  • 21
  • 32
3

I think salt is understood here incorrectly. The idea of salt is that it should be unique per hash. The reason is that when you create hash some different strings may have the same hash.

In your example you're hashing password too so it won't look like: 145ac26ff093c6e1317f7d5fb4c9fd11c77be975password

P.S. Use bcrypt. It's much more reliable.

Leri
  • 12,367
  • 7
  • 43
  • 60
1

Salts are meant to be completely random, and unrelated to the actual password you are storing a hash of.

What you should really do is generate a completely random salt, then do

$password = md5($salt.$password);

and store the user's username, salt and hashed password.

jrharshath
  • 25,975
  • 33
  • 97
  • 127