Skip to content

Instantly share code, notes, and snippets.

@ezimuel
Forked from ircmaxell/password.php
Created June 18, 2012 17:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ezimuel/2949592 to your computer and use it in GitHub Desktop.
Save ezimuel/2949592 to your computer and use it in GitHub Desktop.
Password API Example
<?php
define('PASSWORD_SHA256', '$5$');
define('PASSWORD_SHA512', '$6$');
define('PASSWORD_BCRYPT', '$2y$');
define('PASSWORD_SCRYPT', '$7$'); // made up here
function password_hash($password, $algo = PASSWORD_BCRYPT, array $options = array()) {
$salt = '';
switch ($algo) {
case PASSWORD_SHA256:
case PASSWORD_SHA512:
$rounds = isset($options['rounds']) ? $options['rounds'] : false;
$random = isset($options['salt']) ? $options['salt'] : password_create_salt(16);
$salt = $algo;
if ($rounds) {
$salt .= 'rounds=' . $rounds . '&';
}
$salt .= $random;
break;
case PASSWORD_BCRYPT:
$cost = isset($options['cost']) ? $options['cost'] : 14;
$random = isset($options['salt']) ? $options['salt'] : password_create_salt(22);
$salt = '$2y$' . str_pad($cost, 2, '0', STR_PAD_LEFT) . $random;
break;
break;
default:
trigger_error(E_WARNING, 'Invalid Algorithm Specified');
}
$return = crypt($password, $salt);
if (strlen($return) < 13) {
trigger_error(E_WARNING, 'Crypt Routine Failed');
return false;
}
return $return;
}
function password_validate($password, $hash) {
$testHash = crypt($password, $hash);
$testSalt = password_create_salt(strlen($testHash));
/**
* These should be identical. Run through the same
* hmac algo with a random string to better combat
* side-channel timing attacks
*/
$hash = hash_hmac('sha512', $hash, $testSalt);
$testHash = hash_hmac('sha512', $testHash, $testSalt);
$length = strlen($hash);
$result = 0;
for ($i = 0; $i < $length; $i++) {
$result |= ord($hash[$i]) ^ ord($testHash[$i]);
}
return $result === 0;
}
function password_create_salt($length) {
// Prepare for base64 encoding
$size = ceil($length * 3 / 4);
if (function_exists('openssl_random_pseudo_bytes')) {
$random = openssl_random_pseudo_bytes($size);
} elseif (function_exists('mcrypt_create_iv')) {
$random = mcrypt_create_iv($size, MCRYPT_DEV_URANDOM);
} else {
$random = '';
for ($i = 0; $i < $size; $i++) {
$random .= chr(mt_rand(0, 255));
}
}
// base64 encode it for crypt
$text = base64_encode($random);
$salt = strtr($text, '+', '.');
return substr($salt, 0, $length);
}
<?php
$password = '1234';
$hash = password_hash($password);
if (password_validate($password, $hash)) {}
$hash = password_hash($password, PASSWORD_BCRYPT);
if (password_validate($password, $hash)) {}
$hash = password_hash($password, PASSWORD_BCRYPT, array('cost' => 13));
if (password_validate($password, $hash)) {}
$hash = password_hash($password, PASSWORD_SHA512, array('rounds' => 50000));
if (password_validate($password, $hash)) {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment