I have been reading up on password hashing, but all the forums I read are full of posts from people debating theory behind it that I don’t really understand.
I have an old (and presumably extremely weak) password script that reads like this:
$hash = sha1($pass1);
function createSalt()
{
$string = md5(uniqid(rand(), true));
return substr($string, 0, 3);
}
$salt = createSalt();
$hash = sha1($salt . $hash);
If I understand correctly, the longer the salt, the larger the table the hacker has to generate in order to break the hash. Please correct me if I am wrong.
I am looking to write a new script that is more secure, and I am thinking that something like this would be okay:
function createSalt()
{
$string = hash('sha256', uniqid(rand(), true));
return $string;
}
$hash = hash('sha256', $password);
$salt = createSalt();
$secret_server_hash = 'ac1d81c5f99fdfc6758f21010be4c673878079fdc8f144394030687374f185ad';
$salt2 = hash('sha256', $salt);
$hash = $salt2 . $hash . $secret_server_hash;
$hash = hash('sha512', $hash );
Is this more secure? Does this have a noticeable amount of overhead?
Most importantly, is there some better way to make sure that the passwords in my database cannot be (realistically) recovered by cryptanalysis, thus ensuring that the only way security will be compromised is through my own error in coding?
EDIT:
Upon reading all of your answers and further reasearching, I have decided to go ahead and implement the bcrypt method of protecting my passwords. That being said, for curiosity’s sake, if I were to take my above code and put a loop on it for say, 100,000 iterations, would that accomplish something similar to the strength/security of bcrypt?
Salts can only help you so far. If the hashing algorithm you use is so fast that there is little to no cost for generating rainbow tables, your security is still compromised.
A few pointers:
Instead of deploying your own (inherently with flaws) hash/salt algorithm, why not use one that was developed by security professionals?
Use bcrypt. It’s been developed exactly for this in mind. It slowness and multiple rounds ensures that an attacker must deploy massive funds and hardware to be able to crack your passwords. Add to that per-password salts (bcrypt REQUIRES salts) and you can be sure that an attack is virtually unfeasible without either ludicrous amount of funds or hardware.
The Portable PHP Hashing Framework in non-portable mode allows you to generate hashes using bcrypt easily.
You can also use
crypt()function to generate bcrypt hashes of input strings. If you go down that route, make sure you generate one salt per hash.This class can automatically generate salts and verify existing hashes against an input.
You may use this code as such: