Saturday 28 December 2013

How to Use Bcrypt to Store Hash Passwords in PHP

Storing stronger passwords hash in database is good approach that way you can prevent several security attacks. But no matter how difficult it is to guess good passwords, there may be no more difficult to crack than bad ones depending on how the password is stored. 

Some belive MD5 is a safe way to encode passwords, this is a lie (a very bad one, too)! MD5 is a good method to obscure non-sensitive data but it can be very easily “decoded” using rainbow tables. I once heard the story of a web developer who could not access a client's database after the client deleted an email that had his password details. The developer, after polish thoroughly through the client's files on their server, found a nicely formatted text file containing the MD5 password hash. It was just a quick copy and paste procedure into an online rainbow table lookup utility before they were logged into the client's database. This story has a happy ending as the client's password were recovered and development could continue, but the shocking truth is this process could have easily been carried out by the hands of a nasty hacker. 


Bcrypt


bcrypt is an hashing algorithm which is scalable with hardware (via a configurable number of rounds). Its 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.

bcrypt uses the Eksblowfish algorithm to hash passwords. While the encryption phase of Eksblowfish and Blowfish are exactly the same, the key schedule phase of Eksblowfish ensures that any subsequent state depends on both salt and key (user password), and no state can be precomputed without the knowledge of both. Because of this key difference, bcrypt is a one-way hashing algorithm. You cannot retrieve the plain text password without already knowing the salt, rounds and key (password). Source

Using PHP >= 5.5-DEV

Password hashing functions have now been built directly into PHP >= 5.5. You may now use password_hash() to create a bcrypt hash of any password:


<?php
// Usage 1:
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
// $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

 // Usage 2:
$options = array('cost' => 11);
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
// $2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq

 ?>



To verify a user provided password against an existing hash, you may use the password_verify()as such:


 <?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

 if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>


You can also check if Bcrypt is enabled on your server by checking whether or not the CRYPT_BLOWFISH constant is defined and returns true or false:


 <?php
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
    echo "CRYPT_BLOWFISH is enabled";
}
else {
    echo "CRYPT_BLOWFISH is not enabled";
}
?>


After checking whether CRYPT_BLOWFISH is enabled or not you can simply do the following before saving in database:


 <?php
$hash = '$2a$07$R.gJb2U2N.FmZ4hPp1y2CN$';
crypt("securepassword", $hash);
?>


This is one way to store and make your password cracking secure you can use other PHP libraries too like 
Zend Crypt Password Bcrypt, Doucmentation Source
PasswordLib, Doucmentation Source
PHPASS Doucmentation Code , Project Site

Lastly the importance of using a secure hashing function such as Bcrypt should be vital to anyone creating a web application that will store users’ passwords and other sensitive data because of the fact it will keep up with Moore’s Law and easy to implement with PHP greater than 5.3.

No comments:

Post a Comment