Created
August 17, 2011 16:17
-
-
Save tchalvak/1151912 to your computer and use it in GitHub Desktop.
Simple PHP 5.3+ Bcrypt functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// ================================================================================================================ | |
// Bcrypt hashing and hash checking wrapper functions for simplified, secure password encryption | |
// ================================================================================================================ | |
// Create a bcrypt_hash. | |
function bcrypt_hash($password, $work_factor = 8) | |
{ | |
if (version_compare(PHP_VERSION, '5.3') < 0) throw new Exception('Bcrypt requires PHP 5.3 or above'); | |
if (! function_exists('openssl_random_pseudo_bytes')) { | |
throw new Exception('Bcrypt requires openssl PHP extension'); | |
} | |
if ($work_factor < 4 || $work_factor > 31) $work_factor = 8; | |
$salt = | |
'$2a$' . str_pad($work_factor, 2, '0', STR_PAD_LEFT) . '$' . | |
substr( | |
strtr(base64_encode(openssl_random_pseudo_bytes(16)), '+', '.'), | |
0, 22 | |
) | |
; | |
return crypt($password, $salt); | |
} | |
// Check a password against a bcrypt hash. | |
function bcrypt_check($password, $stored_hash, $legacy_handler = NULL) | |
{ | |
if (version_compare(PHP_VERSION, '5.3') < 0) throw new Exception('Bcrypt requires PHP 5.3 or above'); | |
if (bcrypt_is_legacy_hash($stored_hash)) { | |
if ($legacy_handler) return call_user_func($legacy_handler, $password, $stored_hash); | |
else throw new Exception('Unsupported hash format'); | |
} | |
// Use the php-native function crypt to match the hashes. | |
return crypt($password, $stored_hash) == $stored_hash; | |
} | |
// Check whether the hash was created for bcrypt, or else for some other purpose. | |
function bcrypt_is_legacy_hash($hash) { return substr($hash, 0, 4) != '$2a$'; } | |
/* Sample usage: | |
By Marco Arment <me@marco.org>. | |
This code is released in the public domain. | |
THERE IS ABSOLUTELY NO WARRANTY. | |
Usage example: | |
// In a registration or password-change form: | |
$hash_for_user = Bcrypt::hash($_POST['password']); | |
// Hash the password. | |
// In a login form: | |
// Check the incoming password against the stored hash. | |
$is_correct = Bcrypt::check($_POST['password'], $stored_hash_for_user); | |
// For backwards-compatibility when some entries are hashed using a different method. | |
// In a login form when migrating entries gradually from a legacy SHA-1 hash: | |
$is_correct = Bcrypt::check( | |
$_POST['password'], | |
$stored_hash_for_user, | |
function($password, $hash) { return $hash == sha1($password); } | |
); | |
// This would change from the old hash to using a new hash based on bcrypt. | |
if ($is_correct && Bcrypt::is_legacy_hash($stored_hash_for_user)) { | |
$user->store_new_hash(Bcrypt::hash($_POST['password'])); | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment