Using ‘bcrypt’ to Store Passwords in PHP

I’m not going to go in depth as to why you should or shouldn’t use one method. All I will say is that you should be using bcrypt to store your passwords, if you’re not – well you should! At least reassure me that you’re using a salt!

To do this, we’ll be using the crypt() method with a unique salt. Now many times people think that a salt needs to be unique for that user, which is true in a lot of cases. But with bcrypt we can use a salt that is unique to that password. We don’t even need to store the password at all – as it is actually inside the returned hash itself!

For a salt we can use something like this:

$2a$15$abcdefghijklmnopqrstuv$

The issue with that is the salt isn’t unique, random or unguessable. The letters that are used within the salt are 22 characters from the collection of: ‘./a-zA-Z0-9’. Ideally we should use a random function, which could use either a microtime at the moment, or even some other crazy method! Here’s a more ideal salt:

$2a$15$Ku2hb./9aA71tPo/E015h.$

Let me just quickly break down the salt for you – it’s ultimately in three parts, one of which I’ve already mentioned. The $2a$ section is an identifier that we are using the BlowFish hashing algorithm. The second part the 15 section is the cost parameter. This is in the range of 4-31, and is the interation count for the algorithm.

Very basically it will make it so that bruteforce attacks take longer, if that number is higher. It’s a way to alter how long the password takes to generate.

Now that we have the salt, generating a hash is as simple as doing this:

crypt('password', '$2a$15$Ku2hb./9aA71tPo/E015h.$');

Below are some words & their hashes:

password 	=> 	$2a$15$Ku2hb./9aA71tPo/E015h.LsNjXrZe8pyRwXOCpSnGb0nPZuxeZP2
password2	=> 	$2a$15$Ku2hb./9aA71tPo/E015h.CNGqVsxZZBYTC/r1Os396YragLJGV.W
mypassword	=> 	$2a$15$Ku2hb./9aA71tPo/E015h.h9vBlPsdHlKzNVtKICiGuyZ8A.1ejiy
1234 		=> 	$2a$15$Ku2hb./9aA71tPo/E015h.8Tj1dOqu1OC3tr87Tke2Ef0zrLZ5ooa
pass123 	=> 	$2a$15$Ku2hb./9aA71tPo/E015h.GXUYuw0uJWtFqjpWvgTPoPFOQV09.rG

People always seem to think they have to store a salt – which you might well have to do for other hashes, but with Blowfish you can just use the following line to check that a password is the same as what is stored:

$currentPassword = '$2a$15$Ku2hb./9aA71tPo/E015h.LsNjXrZe8pyRwXOCpSnGb0nPZuxeZP2';
$checkPassword = 'passwords1';

if(crypt($checkPassword, $currentPassword) === $currentPassword){
	echo 'You are in!';
}else{
	echo 'You entered the wrong password';
}
    It’s as simple as that, just remember:

  • Your salt should never be the same for two passwords.
  • You should never store the salt anywhere.
  • Make your salt as random as possible.
  • Never store your password in plain text – ever!
  • You will need to ensure that the host you have is either on PHP 5.3+ or has CRYPT_BLOWFISH

One separate thing that worries me is sites that are able to send you your password to your email address if you forget it. These sites can’t be using a secure hashing method – they should send you a new password, or ask you to go to a URL to enter a new password.