Recently i was reading a book regarding a safe way to store a password in the database. The book started with MD5, SHA1, and CRYPT_BLOWFISH. From what i read i understand that the safer way to store passwords is by using CRYPT along with random salt per user(a value that the user inserts in while registrating, like username for example), without storing the salt in the database.
So, lets say that i generate a salt:
$salt = '$2y$11$';
$salt = $salt.md5($username);
As we know a MD5 hash is a 32 character long string. So 7+32 = 39 character string = SALT
Something like this: $2y$11$243dc6440dfd91e35a773035da362f4e
Then i generate the hash using crypt()
:
$hash = crypt($password,$salt);
The crypt hash always results in a 60 character string. The result is:
$2y$11$243dc6440dfd91e35a773uY4TBuP14hk.KZq4VvOWV8EhT03Vj8Tu
If a hacker gain access to the database, he/she will see the part $2y$11$
of the 60 character string above.
My question is: Is this info helpful for the hacker (knowing the hashing method and the cost)?
Should I store the hash omitting that part? 243dc6440dfd91e35a773uY4TBuP14hk.KZq4VvOWV8EhT03Vj8Tu
Will this make things worse for the hacker?
Other than these, are there any other suggestions regarding password security AFTER the hacker gains access to the database?
There is a tutorial i wrote about safely storing passwords, it explains why it is not necessary to hide the hash parameters.
If you hide this parameters you actually add a server side secret (an attacker has to guess the algorithm and the cost factor). There are much better ways to add such a secret though, have a look at the last part of the tutorial about encrypting the hash-value with a server side key.
A salt is used to defend against dictionary attacks and rainbow table attacks becasue the resulting hash is different due to the randomly generated salt which was added to the password.
The salt is saved with the hash so that the hash can be regenerated from the password+salt.
So because of this the salt needs to be saved and so what you have done is one possible way of doing this.
The reason this is not helpful to the hacker and won't make things easier is because the whole point of a hashing algorithm is it's resistance to being reversed. Dictionary attacks and rainbow tables work by using known hashes that have been derived from a "word" to a hash. With an added random number in front of the original "word" the hash is completely different and so to create a dictionary or rainbow table with all possible salt values (for a given length salt) would be a huge database and take way too much time for the hacker to crack or even bother attempting.
The system appears to be a 3 part system.
- A Salt to prevent Rainbow Table Attacks.
- The Salt itself is protected by using some pseudo random data.
The Base Salt and the pseudo random data is mixed and used as the Final Salt.
- With the 3 parts above you have a system that is resistant to Rainbow
Table attacks (1).
- The System is further resistant to Finding a Rainbow
Table for your Salt. (2).
- So if your system is compromised, an
attacker would have to generate a Rainbow Table for each User
Account. This is essentially equivalent to cracking that/each users
password. (3).
Or so Would the theory go.