note 109156 added to function.hash-hmac
| From: | EdwardHoffman | Date: | Sun, 24 Jun 2012 15:42:56 +0000 |
| Subject: | note 109156 added to function.hash-hmac | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-188775@lists.php.net to get a copy of this message | ||
The following implementation of PBKDF2 by Defuse Cyber Security is a lot faster than some already
mentioned here. I don't know why that is the case but I've tested various algorithms,
iteration counts, etc. and it's always faster and the resulting hashes are the same.
<?php
/*
* PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
* $algorithm - The hash algorithm to use. Recommended: SHA256
* $password - The password.
* $salt - A salt that is unique to the password.
* $count - Iteration count. Higher is better, but slower. Recommended: At least 1024.
* $key_length - The length of the derived key in BYTES.
* Returns: A $key_length-byte key derived from the password and salt (in binary).
*
* Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
*/
function pbkdf2($algorithm, $password, $salt, $count, $key_length)
{
$algorithm = strtolower($algorithm);
if(!in_array($algorithm, hash_algos(), true))
die('PBKDF2 ERROR: Invalid hash algorithm.');
if($count <= 0 || $key_length <= 0)
die('PBKDF2 ERROR: Invalid parameters.');
// number of blocks = ceil(key length / hash length)
$hash_length = strlen(hash($algorithm, "", true));
$block_count = $key_length / $hash_length;
if($key_length % $hash_length != 0)
$block_count += 1;
$output = "";
for($i = 1; $i <= $block_count; $i++)
{
$output .= pbkdf2_f($password, $salt, $count, $i, $algorithm, $hash_length);
}
return substr($output, 0, $key_length);
}
/*
* The pseudorandom function used by PBKDF2.
* Definition: https://www.ietf.org/rfc/rfc2898.txt
*/
function pbkdf2_f($password, $salt, $count, $i, $algorithm, $hash_length)
{
//$i encoded as 4 bytes, big endian.
$last = $salt . chr(($i >> 24) % 256) . chr(($i >> 16) % 256) . chr(($i
>> 8) % 256) . chr($i % 256);
$xorsum = "";
for($r = 0; $r < $count; $r++)
{
$u = hash_hmac($algorithm, $last, $password, true);
$last = $u;
if(empty($xorsum))
$xorsum = $u;
else
{
for($c = 0; $c < $hash_length; $c++)
{
$xorsum[$c] = chr(ord(substr($xorsum, $c, 1)) ^ ord(substr($u, $c, 1)));
}
}
}
return $xorsum;
}
?>
----
Server IP: 69.147.83.197
Probable Submitter: 84.146.248.152
----
Manual Page -- http://www.php.net/manual/en/function.hash-hmac.php
Edit -- https://master.php.net/note/edit/109156
Del: integrated -- https://master.php.net/note/delete/109156/integrated
Del: useless -- https://master.php.net/note/delete/109156/useless
Del: bad code -- https://master.php.net/note/delete/109156/bad+code
Del: spam -- https://master.php.net/note/delete/109156/spam
Del: non-english -- https://master.php.net/note/delete/109156/non-english
Del: in docs -- https://master.php.net/note/delete/109156/in+docs
Del: other reasons-- https://master.php.net/note/delete/109156
Reject -- https://master.php.net/note/reject/109156
Search -- https://master.php.net/manage/user-notes.php