3

I've been investigating better procedures for securing passwords in php applications. Formally I would have used something similar to (just an example, don't shoot!):

$salt = md5(rand() . md5(rand() . '$%E$%SDRT');
$password = md5('supersecret', $salt);

I would then generate a different salt for every password in the database to prevent the use of rainbow tables.

Looking online though it seems that most (wise) people are moving towards bcrypt(). There are plenty of questions as to how it works, why it works etc, but what I don't understand is how it is more secure? Note that I may have got muddled up with my understanding here

It is my understanding that when you use crypt($pass, $salt) the salt actually works as an indicator for crypt to tell it what algorthim to use. According to the php manual you use "$2a$07" which tells crypt to use blowfish at log2 rounds. It then spits out a string which contains the salt as a prefix.

example from the manual:

Blowfish:     $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi

It also seems that the salt remains static for all the passwords. I don't get how this is secure. It seems even easier for the hacker to find the salt (don't even need to pull from salt column) and there is a beacon at the start indicating the rounds and algorithm used. How can this be more secure? I know that more rounds puts a higher toll on hardware, makes it scalable and increases the time it takes to crack the password (due to cost), but it also indicates exactly how it was done.

Also, I'm someone who likes to code as much of my application myself as possible in order to gain a higher understanding of the workings and would prefer to stay away from openwall if possible. I don't like being dependent on other peoples code and in turn absorbing their vulnerabilities. I would rather be responsible for my own vulnerabilities and fix them myself.

One more thing. If you increase the number of rounds does that not mean that current passwords hashes will not match that of the hash in the database? Do you have to reset all users passwords or do you slowly move them towards the new number of rounds on their next login?

As I say this is simply my understanding so it may just be my understanding that is mixed up. I don't think this is one of those instances where you can just "try and fail" because if you fail you might looking at more than a broken application...

What I have been reading:

What is the correct format for a blowfish salt using PHP's crypt?
PHP Manual - Crypt
Openwall phpass
How to create and store password hashes with Blowfish in PHP
How do you use bcrypt for hashing passwords in PHP?

Community
  • 1
  • 1
Sam
  • 1,564
  • 4
  • 23
  • 37
  • If you increase the rounds the hashes will change. You can mark who has not been "rehashed"; if they are authenticated, take their inputted password, rehash it, store it, and mark them has updated. – Raekye Jan 21 '13 at 07:09
  • `but it also indicates exactly how it was done.` The attacker will always know how it was done no matter what you use. EDIT: The point of you preferring to code it yourself rather than use a tested solution is (at least in this case) plain stupid and will do more harm to your application than any plain-text password storing ever could. – mishmash Jan 21 '13 at 07:12
  • That was one of the main reasons I asked the question – Sam Jan 21 '13 at 08:09

2 Answers2

0

As I understand your question is "Why hashing with variable salt is more secure?".

There is only one thing: it is always bruteforce, and if the salt is constant, it is possible to "hack" all the passwords with only one bruteforce cycle. (If hash is equal to one from the database - we know the user password).

For simple md5() and sha1() hash functions it is also possible to store generated hashes of brutforced passwords in the database (for future use). Such method allows hacker to determine almost all passwords in seconds.

clover
  • 4,910
  • 1
  • 18
  • 26
0

It also seems that the salt remains static for all the passwords. I don't get how this is secure.

You need to use the bcrypt a bit differently. Do not pass the real password as a password parameter. You can prepend, append or put in the middle of the string some generated "salt" string. Then store the salt with the output hash to your storage.

When the user inputs his/her password then get the salt, do the same thing again with the salt and bcrypt() and compare the results with your stored hash.

Using salt in this way blocks using normal rainbow tables as mentioned by @clover.

Also simpler solution is usually better solution. Simple rand() should be enough for a password salt.

Antti Rytsölä
  • 1,485
  • 14
  • 24
  • Without salt it is easy to find all the users from the storage with the password GOD – Antti Rytsölä Jan 21 '13 at 14:32
  • Please explain. Why would that be? – Sam Jan 21 '13 at 18:59
  • The presumption is that the attacker gets the copy of the database. Then he has the hashes and the code. He makes the hash of the word GOD and check if the hash correspondences to any stored hash in the database. With salts this is not possible as every user has different hash in the database. – Antti Rytsölä Jan 23 '13 at 12:47