sms sms - 7 months ago 14
PHP Question

Secure password generation and storage

I'm building a login system and I want to be sure I'm writing the write code to generate and store passwords in the db.

$options['passwd']
is the string selected as a password by the user.

This is my code to generate a hash:

public function createPasswd($options) {
$hash_seed = 'm9238asdasdasdad31d2131231231230132k32ka¡2da12sm2382329';
$password = $options['passwd'];
$date = new DateTime();
$timestamp = $date->getTimestamp();
$rand_number = rand($timestamp,$timestamp + pow(91239193912939123912,3));
$rand = pow($rand_number, 12);
$salt = str_shuffle($rand.$hash_seed);
$hash = crypt($password, $salt);
return $hash;
}//End class createPasswd


I just store the hash on the database and then compare it with user's password like the following:

if ($hash == crypt($password, $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}


Is this strong enough? Am I missing some big issue?.

Answer

Longer salt doesn't mean better protection. You don't use crypt function properly. $salt argument should not be a simple random string.

Consider this exemple :

echo crypt('password one', 'salt lorem ipsum dolor sit amet');  
echo crypt('password two', 'salt');

Both will return the same string ! (sa3tHJ3/KuYvI)

Check http://php.net/crypt for more information about how to use $salt the correct way.

It's also much better (safer?) to keep an unique hash_seed code side and then store in the database only a sha hash (or other algo) of a string combining the password and your hash_seed.

Correct implementation would be :

define('SECRET_KEY', 'm9238asdasdasdad31d2131231231230132k32ka¡2da12sm2382329');  // longer is better

public function createPasswd($options) {
    return hash('sha256', SECRET_KEY . $options['passwd']);
}

To check the password :

if ($stored_hash == hash('sha256', SECRET_KEY . $password) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

sha256 can be replaced with any available algorithms on your system. Get the complete list with :

var_dump(hash_algos());