Skip to content

Instantly share code, notes, and snippets.

@mattattui
Last active May 17, 2016 09:23
Show Gist options
  • Save mattattui/1162409 to your computer and use it in GitHub Desktop.
Save mattattui/1162409 to your computer and use it in GitHub Desktop.
PHP PBKDF2 implementation
<?php
/* PHP PBKDF2 implementation
*
* PBKDF2 is a key derivation function defined in RFC2898. It's used to
* generate longer and more secure passwords from short, human-entered
* passwords. The number of rounds can be increased to keep ahead of
* improvements in CPU/GPU performance.
*
* You should use a different salt for each password (it's safe to store it
* alongside your generated password; much safer than using the same salt for
* multiple passwords, anyway).
*
* This function is slow; that's intentional! You should use at least 5000
* rounds in 2011.
*
* For more information see:
* - http://en.wikipedia.org/wiki/PBKDF2
* - http://www.ietf.org/rfc/rfc2898.txt
*
* This implementation is very slightly modified from the one found here:
* http://www.php.net/manual/en/function.hash-hmac.php#101540
*
* The variable names have been made readable, some have sensible defaults,
* and the output is Base64 encoded. Argument ordering changed to match
* the builtin version in PHP 5.5.
*/
function hash_pbkdf2($a = 'sha256', $password, $salt, $rounds = 5000, $key_length = 32, $raw_output = false)
{
// Derived key
$dk = '';
// Create key
for ($block=1; $block<=$key_length; $block++)
{
// Initial hash for this block
$ib = $h = hash_hmac($a, $salt . pack('N', $block), $password, true);
// Perform block iterations
for ($i=1; $i<$rounds; $i++)
{
// XOR each iteration
$ib ^= ($h = hash_hmac($a, $h, $password, true));
}
// Append iterated block
$dk .= $ib;
}
// Return derived key of correct length
$key = substr($dk, 0, $key_length);
return $raw_output ? $key : base64_encode($key);
}
@mattattui
Copy link
Author

Updated function definition to match the proposed built-in implementation announced for PHP 5.5 (except that the default algorithm here is still sha256, not sha512).

@JMLamodiere
Copy link

👎 WARNING : this function is not compatible with the one shipped with PHP 5.5 :

  • The default $key_length is 32 instead of 0
  • When passing 32, The returned string is much longer than 32 (due to the base64_encode), whereas it is 32 with the PHP5.5 one.

You will also have a conflict in function name when upgrading to PHP5.5 if you forget to wrap it inside a if (!function_exists('hash_pbkdf2')) {

Suggestion : use https://github.com/symfony/polyfill-php55 instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment