11

After a few days reading up about salting and hashing passwords, I found an actual bit of code that tells how to do it. This is what I found:

$blowfish_salt = bin2hex(openssl_random_pseudo_bytes(22));  
$hash = crypt($data, "$2a$12$".$blowfish_salt);  

Is this a good way to do it?

3 Answers 3

14
  1. It's easier to use the php 5.5 password_hash function, or if you're using an older version, the compatibility library
  2. openssl_random_pseudo_bytes sometimes suffers from performance issues. Consider mcrypt_create_iv (size, MCRYPT_DEV_URANDOM) instead.
  3. salt encoding is tricky. Hex doesn't use the space optimally, and normal Base64 uses invalid characters.

    $salt = substr(strtr(base64_encode($randomSalt), '+', '.'), 0, 22);
    

    should do the trick.

Combining these you get

$binarySalt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$salt = substr(strtr(base64_encode($binarySalt), '+', '.'), 0, 22);

Check Seven Ways To Screw Up BCrypt on ircmaxell's blog for further reading.

4
  • Thanks @CodesInChaos! (Remembering I am totally new to this) would you mind putting the two suggestions together so that I can begin to understand how it should go? (I'd understand if you say no - but I have been going round and round for the last couple of days,for just that one code snippet and my brains are getting totally fried!)
    – vinaya
    Jul 24, 2013 at 12:19
  • 1
    @vinaya I recommend using the password_hash library I linked, instead of writing it yourself. Jul 24, 2013 at 12:25
  • Some source related to the performance issues of openssl_random_pseudo_bytes()?
    – gipi
    Jul 31, 2013 at 12:33
  • @gipi I don't remember the details, but I guess it was this issue: stackoverflow.com/questions/1940168/… Jul 31, 2013 at 12:43
2

There isn't anything wrong with your code. However, I always prefer to use ready made libraries for password hashing whenever possible. For PHP, there is an excellent implementation available over at PHPass.

require('PasswordHash.php');

$pwdHasher = new PasswordHash(8, FALSE);

$hash = $pwdHasher->HashPassword( $password );

Verification is done for you as well.

$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}
0

You are doing it correctly. The salt you are generating is considered random and long enough (note a salt needs to be unique per password). You are also using bcrypt which is considered a secure password hashing algorithm.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .