< < Gregphoto.net Blog

PasswordHelper: PHP password utility library

Overview

PasswordHelper is a lightweight BSD licensed PHP class that has a number of password related utility functions that make it easy to: The library does nothing too complex - it just makes it easy to do common things to help create more secure PHP applications utilizing existing PHP functions through a simpler API. Most of the existing APIs seem a bit...cryptic (ha ha, right?) and there are so many options and algorithms from which to choose. Choosing the 'wrong' algorithm for password hashing can lead to big problems, like the ability for hackers to brute force hundreds of thousands of passwords from your database in an hour.

In How to Safely Store a Password, Coda Hale writes:
How much slower is bcrypt than, say, MD5? Depends on the work factor. Using a work factor of 12, bcrypt hashes the password yaaa in about 0.3 seconds on my laptop. MD5, on the other hand, takes less than a microsecond.

So we're talking about 5 or so orders of magnitude. Instead of cracking a password every 40 seconds, I'd be cracking them every 12 years or so. Your passwords might not need that kind of security and you might need a faster comparison algorithm, but bcrypt allows you to choose your balance of speed and security. Use it.
PasswordHelper for PHP uses Blowfish/bcrypt to make it easy for you to more securely store passwords for your users and throws in a couple extra helper functions for generating random passwords and checking the complexity of user passwords.

PasswordHelper requires either PHP 5.3 or greater or an underlying operating system that supports the Blowfish/bcrypt algorithm.

I hope you find it helpful!
Download PasswordHelper

Available methods

Password Hashing and Comparison

Password Generation

Password Complexity Validation

Example Code

<?php
require('PasswordHelper.php');

$pass = new PasswordHelper();

// Password hashing examples
$hash $pass->generateHash('myP@ssword');
echo 
"Hash 'myP@ssword' with default cost factor of 10: " $hash "<br>";

$hash $pass->generateHash('myP@ssword'12);
echo 
"Hash 'myP@ssword' with cost factor of 12: " $hash "<br>";

$result $pass->compareToHash('myWrongPassword'$hash);
echo 
"Compare incorrect password 'myWrongPassword' with hashed password: " booleanToString($result) . "<br>";

$result $pass->compareToHash('myP@ssword'$hash);
echo 
"Compare correct password 'myP@ssword' with hashed password: " booleanToString($result) . "<br><br>";


// Password generation examples
echo "Random passwords of different lengths:<br>";
echo 
"8 (Default): " $pass->generateRandomPassword() . '<br>';
echo 
"8 (Default): " $pass->generateRandomPassword() . '<br>';
echo 
"10: " $pass->generateRandomPassword(10) . '<br>';
echo 
"12: " $pass->generateRandomPassword(12) . '<br>';
echo 
"6: " $pass->generateRandomPassword(6) . '<br><br>';

// Password complexity validation
echo 'Validate password complexity for various passwords:<br>';
$passwords = array('test','Test12#','Test123$','myPassword!');
foreach(
$passwords as $password) {
    echo 
"'{$password}': " booleanToString($pass->checkPasswordComplexity($password)) . "<br>";
}

function 
booleanToString($bool) {
    return (
$bool) ? 'true' 'false';
}
...and an example of the resulting output:

Hash 'myP@ssword' with default cost factor of 10: $2a$10$9.oGr9JUazV2PL9OgfDNQ.xrchVDP1whIzxZbhDV8WFXa3Bm.ixIq
Hash 'myP@ssword' with cost factor of 12: $2a$12$CSuP/F38LU.aZ3TptOV/tunz8Dt2q.d3iXsvuwbXQG.PSNyTB1poq
Compare incorrect password 'myWrongPassword' with hashed password: false
Compare correct password 'myP@ssword' with hashed password: true

Random passwords of different lengths:
8 (Default): YtStdf^d
8 (Default): Wyd6JA^b
10: $Kw5CGKe@z
12: NDTumv5v6cDm
6: 3xQH#a

Validate password complexity for various passwords:
'test': false
'Test12#': false
'Test123$': true
'myPassword!': true