hash_pbkdf2

(PHP 5 >= 5.5.0)

hash_pbkdf2Generate a PBKDF2 key derivation of a supplied password

Description

string hash_pbkdf2 ( string $algo , string $password , string $salt , int $iterations [, int $length = 0 [, bool $raw_output = false ]] )

Parameters

algo

Name of selected hashing algorithm (i.e. md5, sha256, haval160,4, etc..) See hash_algos() for a list of supported algorithms.

password

The password to use for the derivation.

salt

The salt to use for the derivation. This value should be generated randomly.

iterations

The number of internal iterations to perform for the derivation.

length

The length of the output string. If raw_output is TRUE this corresponds to the byte-length of the derived key, if raw_output is FALSE this corresponds to twice the byte-length of the derived key (as every byte of the key is returned as two hexits).

If 0 is passed, the entire output of the supplied algorithm is used.

raw_output

When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.

Return Values

Returns a string containing the derived key as lowercase hexits unless raw_output is set to TRUE in which case the raw binary representation of the derived key is returned.

Errors/Exceptions

An E_WARNING will be raised if the algorithm is unknown, the iterations parameter is less than or equal to 0, the length is less than 0 or the salt is too long (greater than INT_MAX - 4).

Examples

Example #1 hash_pbkdf2() example, basic usage

<?php
$password 
"password";
$iterations 1000;

// Generate a random IV using mcrypt_create_iv(),
// openssl_random_pseudo_bytes() or another suitable source of randomness
$salt mcrypt_create_iv(16MCRYPT_DEV_URANDOM);

$hash hash_pbkdf2("sha256"$password$salt$iterations20);
echo 
$hash;
?>

The above example will output something similar to:

120fb6cffcf8b32c43e7

Notes

Caution

The PBKDF2 method can be used for hashing passwords for storage. However, it should be noted that password_hash() or crypt() with CRYPT_BLOWFISH are better suited for password storage.

See Also

  • crypt() - One-way string hashing
  • password_hash() - Creates a password hash
  • hash() - Generate a hash value (message digest)
  • hash_algos() - Return a list of registered hashing algorithms
  • hash_init() - Initialize an incremental hashing context
  • hash_hmac() - Generate a keyed hash value using the HMAC method
  • hash_hmac_file() - Generate a keyed hash value using the HMAC method and the contents of a given file

Коментарии

Автор:
Sadly this function was added in PHP 5.5 but many webservers just provide PHP 5.3. But there exists a pure PHP implementation (found here: https://defuse.ca/php-pbkdf2.htm).
I took this implementation, put it into a class with comments for PHPDoc and added a switch so that the native PHP function is used if available.

Feel free to use it!
http://pastebin.com/f5PDq735
(Posted on pastebin.com since the text would have been too long)
2013-07-13 19:29:31
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
Автор:
People who wants pure PHP implementation of the function, i.e. who don't have PHP 5.5 installed within their server, can use the following implementation. Nothing has been modified so far as from reference https://defuse.ca/php-pbkdf2.htm but the OOP lovers might like this.
For more information about PBKDF2 see: http://en.wikipedia.org/wiki/PBKDF2

<?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 1000.
 * $key_length - The length of the derived key in bytes.
 * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
 * Returns: A $key_length-byte key derived from the password and salt.
 */
if (!function_exists("hash_pbkdf2")) {
    function 
hash_pbkdf2($algorithm$password$salt$count$key_length$raw_output false) {

        class 
pbkdf2 {
            public 
$algorithm;
            public 
$password;
            public 
$salt;
            public 
$count;
            public 
$key_length;
            public 
$raw_output;

            private 
$hash_length;
            private 
$output         "";

            public function 
__construct($data null)
            {
                if (
$data != null) {
                   
$this->init($data);
                }
            }

            public function 
init($data)
            {
               
$this->algorithm  $data["algorithm"];
               
$this->password   $data["password"];
               
$this->salt       $data["salt"];
               
$this->count      $data["count"];
               
$this->key_length $data["key_length"];
               
$this->raw_output $data["raw_output"];
            }

            public function 
hash()
            {
               
$this->algorithm strtolower($this->algorithm);
                if(!
in_array($this->algorithmhash_algos(), true))
                    throw new 
Exception('PBKDF2 ERROR: Invalid hash algorithm.');

                if(
$this->count <= || $this->key_length <= 0)
                    throw new 
Exception('PBKDF2 ERROR: Invalid parameters.');

               
$this->hash_length strlen(hash($this->algorithm""true));
               
$block_count ceil($this->key_length $this->hash_length);
                for (
$i 1$i <= $block_count$i++) {
                   
// $i encoded as 4 bytes, big endian.
                   
$last $this->salt pack("N"$i);
                   
// first iteration
                   
$last $xorsum hash_hmac($this->algorithm$last$this->passwordtrue);
                   
// perform the other $this->count - 1 iterations
                   
for ($j 1$j $this->count$j++) {
                       
$xorsum ^= ($last hash_hmac($this->algorithm$last$this->passwordtrue));
                    }
                   
$this->output .= $xorsum;
                    if(
$this->raw_output)
                        return 
substr($this->output0$this->key_length);
                    else
                        return 
bin2hex(substr($this->output0$this->key_length));
                }
            }
        }

       
$data = array('algorithm' => $algorithm'password' => $password'salt' => $salt'count' => $count'key_length' => $key_length'raw_output' => $raw_output);
        try {
           
$pbkdf2 = new pbkdf2($data);
            return 
$pbkdf2->hash();
        } catch (
Exception $e) {
            throw 
$e;
        }
    }
}
2013-10-18 01:25:03
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
this snippet was posted over a year ago on a dutch PHP community: (reference/source: http://www.phphulp.nl/php/script/beveiliging/pbkdf2-een-veilige-manier-om-wachtwoorden-op-te-slaan/1956/pbkdf2php/1757/)

<?php

/**
 * @author Chris Horeweg
 * @package Security_Tools
 */

function pbkdf2($password$salt$algorithm 'sha512'$count 20000$key_length 128$raw_output false)
{
    if(!
in_array($algorithmhash_algos(), true)) {
        exit(
'pbkdf2: Hash algoritme is niet geinstalleerd op het systeem.');
    }
   
    if(
$count <= || $key_length <= 0) {
       
$count 20000;
       
$key_length 128;
    }

   
$hash_length strlen(hash($algorithm""true));
   
$block_count ceil($key_length $hash_length);

   
$output "";
    for(
$i 1$i <= $block_count$i++) {
       
$last $salt pack("N"$i);
       
$last $xorsum hash_hmac($algorithm$last$passwordtrue);
        for (
$j 1$j $count$j++) {
           
$xorsum ^= ($last hash_hmac($algorithm$last$passwordtrue));
        }
       
$output .= $xorsum;
    }

    if(
$raw_output) {
        return 
substr($output0$key_length);
    }
    else {
        return 
base64_encode(substr($output0$key_length));
    }
}
2013-10-25 18:30:37
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
Автор:
See also https://github.com/rchouinard/hash_pbkdf2-compat for a compatibility function
2013-11-21 17:03:18
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
Автор:
This is a light-weight drop-in replacement for PHP's hash_pbkdf2(); written for compatibility with older versions of PHP.
Written, formatted and tested by myself, but using code and ideas based on the following:
https://defuse.ca/php-pbkdf2.htm
https://github.com/rchouinard/hash_pbkdf2-compat/blob/master/src/hash_pbkdf2.php
https://gist.github.com/rsky/5104756

My main goals:
1) Maximum compatibility with PHP hash_pbkdf2(), ie. a drop-in replacement function
2) Minimum code size/bloat
3) Easy to copy/paste
4) No classes, and not encapsulated in a class! Why write a class when a simple function will do?
5) Eliminate calls to sprintf(). (used by other examples for the error reporting)
6) No other dependencies, ie. extra required functions

<?php
if (!function_exists('hash_pbkdf2'))
{
    function 
hash_pbkdf2($algo$password$salt$count$length 0$raw_output false)
    {
        if (!
in_array(strtolower($algo), hash_algos())) trigger_error(__FUNCTION__ '(): Unknown hashing algorithm: ' $algoE_USER_WARNING);
        if (!
is_numeric($count)) trigger_error(__FUNCTION__ '(): expects parameter 4 to be long, ' gettype($count) . ' given'E_USER_WARNING);
        if (!
is_numeric($length)) trigger_error(__FUNCTION__ '(): expects parameter 5 to be long, ' gettype($length) . ' given'E_USER_WARNING);
        if (
$count <= 0trigger_error(__FUNCTION__ '(): Iterations must be a positive integer: ' $countE_USER_WARNING);
        if (
$length 0trigger_error(__FUNCTION__ '(): Length must be greater than or equal to 0: ' $lengthE_USER_WARNING);

       
$output '';
       
$block_count $length ceil($length strlen(hash($algo''$raw_output))) : 1;
        for (
$i 1$i <= $block_count$i++)
        {
           
$last $xorsum hash_hmac($algo$salt pack('N'$i), $passwordtrue);
            for (
$j 1$j $count$j++)
            {
               
$xorsum ^= ($last hash_hmac($algo$last$passwordtrue));
            }
           
$output .= $xorsum;
        }

        if (!
$raw_output$output bin2hex($output);
        return 
$length substr($output0$length) : $output;
    }
}
2015-11-11 15:45:33
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
There is a mistake in the class provided by Binod Kumar Luitel (function.hash-pbkdf2#113488):
this line:
return bin2hex(substr($this->output, 0, $this->key_length));
must be changed to:
return substr(bin2hex($this->output), 0, $this->key_length);
2016-01-05 14:08:28
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
Please pay great attention to the **$length** parameter! It is exactly the **return string length**, NOT the length of raw binary hash result.

I had a big problem about this -- 
I thought that `hash_pbkdf2(...false)` should equals to `bin2hex(hash_pbkdf2(...true))` just like `md5($x)` equals `bin2hex(md5($x, true))`. However I was wrong:

hash_pbkdf2('sha256', '123456', 'abc', 10000, 50, false); // returns string(50) "584bc5b41005169f1fa15177edb78d75f9846afc466a4bae05"
hash_pbkdf2('sha256', '123456', 'abc', 10000, 50, true); // returns string(50) "XKŴ��Qw�u��j�FjK���BFW�YpG    �mp.g2�`;N�"
bin2hex(hash_pbkdf2('sha256', '123456', 'abc', 10000, 50, true)); // returns string(100) "584bc5b41005169f1fa15177edb78d75f9846afc466a4bae05119c82424657c81b5970471f098a6d702e6732b7603b194efe"

So I add such a note. Hope it will help someone else like me.
2016-09-06 11:40:57
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
Автор:
Note that if $raw_output is false, then the output will be encoded using lowercase hexits. Some other systems (such as Django 2.0) use base64 instead. So if you're trying to generate hash strings that are compatible with those systems, you can use the base64_encode function, like this:

<?php

echo base64_encodehash_pbkdf2"sha256""example password""BbirbJq1C1G7"1000000true ) );

?>
2018-01-12 18:56:28
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
This is a very basic implementation of Rfc2898DeriveBytes class with only 2 of its constructors in case someone else finds it useful.

class Rfc2898DeriveBytes
{
    private $textToHash;
    private $saltByteSize;
   
    public $salt;
   
    public function __construct($arg1, $arg2)
    {
        if (is_string($arg1) && is_integer($arg2)) {
            $this->textToHash = $arg1;
            $this->saltByteSize = $arg2;
            $this->salt = substr(
                hex2bin(sha1(uniqid('', true))),
                0,
                $this->saltByteSize
            );
        } elseif (is_string($arg1) && is_string($arg2)) {
            $this->textToHash = $arg1;
            $this->salt = $arg2;
        }
    }
   
    public function getBytes($size)
    {
        return hash_pbkdf2(
            "sha1",
            $this->textToHash,
            $this->salt,
            1000,
            $size,
            true
        );
    }
}
2019-07-02 15:16:15
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
Автор:
On an error hash_pbkdf2() will not just raise an E_WARNING but it will also return FALSE.
2019-10-19 21:24:58
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
If you are wondering what the requirements are for the salt, have a look at the RFC[1]:

"The salt parameter should be a random string containing at least 64 bits of entropy. That means when generated from a function like *mcrypt_create_iv*, at least 8 bytes long. But for salts that consist of only *a-zA-Z0-9* (or are base_64 encoded), the minimum length should be at least 11 characters. It should be generated random for each password that's hashed, and stored along side the generated key."

[1] https://wiki.php.net/rfc/hash_pbkdf2
2021-02-04 14:55:36
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
If you are wondering what the requirements are for the salt, have a look at the RFC[1]:

"The salt parameter should be a random string containing at least 64 bits of entropy. That means when generated from a function like *mcrypt_create_iv*, at least 8 bytes long. But for salts that consist of only *a-zA-Z0-9* (or are base_64 encoded), the minimum length should be at least 11 characters. It should be generated random for each password that's hashed, and stored along side the generated key."

[1] https://wiki.php.net/rfc/hash_pbkdf2
2021-02-04 14:56:19
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html
If you are wondering what the requirements are for the salt, have a look at the RFC[1]:

"The salt parameter should be a random string containing at least 64 bits of entropy. That means when generated from a function like *mcrypt_create_iv*, at least 8 bytes long. But for salts that consist of only *a-zA-Z0-9* (or are base_64 encoded), the minimum length should be at least 11 characters. It should be generated random for each password that's hashed, and stored along side the generated key."

[1] https://wiki.php.net/rfc/hash_pbkdf2
2021-02-04 14:57:37
http://php5.kiev.ua/manual/ru/function.hash-pbkdf2.html

    Поддержать сайт на родительском проекте КГБ