Skip to content

Instantly share code, notes, and snippets.

@jlyon
Last active August 29, 2015 14:06
Show Gist options
  • Save jlyon/3d1692b37463f82a32ac to your computer and use it in GitHub Desktop.
Save jlyon/3d1692b37463f82a32ac to your computer and use it in GitHub Desktop.
Drupal password encryption
<?php
// Remove the asterisks with real values
$username = '2*****charity';
$hashed_password = '$S$Dk9wYRxEp7GmdP4tVn05MIlcIpzfCFH2sDsS.coi8HMnL.RtIvse';
$password = "22***VA";
if (check_password($password, $hashed_password)) {
echo 'passes';
}
else {
echo 'bad password';
}
function check_password($password, $hashed_password) {
$algo = 'sha512';
$setting = $hashed_password;
// The first 12 characters of an existing hash are its setting string.
$setting = substr($setting, 0, 12);
$itoa64 = _password_itoa64();
$count_log2 = strpos($itoa64, $setting[3]);
$salt = substr($setting, 4, 8);
// Hashes must have an 8 character salt.
if (strlen($salt) != 8) {
return FALSE;
}
// Convert the base 2 logarithm into an integer.
$count = 1 << $count_log2;
// We rely on the hash() function being available in PHP 5.2+.
$hash = hash($algo, $salt . $password, TRUE);
do {
$hash = hash($algo, $hash . $password, TRUE);
} while (--$count);
$len = strlen($hash);
$output = $setting . _password_base64_encode($hash, $len);
// _password_base64_encode() of a 16 byte MD5 will always be 22 characters.
// _password_base64_encode() of a 64 byte sha512 will always be 86 characters.
$expected = 12 + ceil((8 * $len) / 6);
$hash = (strlen($output) == $expected) ? substr($output, 0, 55) : FALSE;
return ($hash && $hashed_password == $hash);
}
function _password_itoa64() {
return './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
}
function _password_base64_encode($input, $count) {
$output = '';
$i = 0;
$itoa64 = _password_itoa64();
do {
$value = ord($input[$i++]);
$output .= $itoa64[$value & 0x3f];
if ($i < $count) {
$value |= ord($input[$i]) << 8;
}
$output .= $itoa64[($value >> 6) & 0x3f];
if ($i++ >= $count) {
break;
}
if ($i < $count) {
$value |= ord($input[$i]) << 16;
}
$output .= $itoa64[($value >> 12) & 0x3f];
if ($i++ >= $count) {
break;
}
$output .= $itoa64[($value >> 18) & 0x3f];
} while ($i < $count);
return $output;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment