rfc:hash_pbkdf2

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:hash_pbkdf2 [2012/06/14 01:59] – Make it draft ircmaxellrfc:hash_pbkdf2 [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== Request for Comments: Adding hash_pbkdf2 Function ====== ====== Request for Comments: Adding hash_pbkdf2 Function ======
-  * Version: 0.1+  * Version: 1.0
   * Date: 2012-06-13   * Date: 2012-06-13
-  * Author: Anthony Ferrara <me@ircmaxell.com+  * Author: Anthony Ferrara <ircmaxell@php.net
-  * Status: Draft+  * Status: Implemented
   * First Published at: http://wiki.php.net/rfc/hash_pbkdf2   * First Published at: http://wiki.php.net/rfc/hash_pbkdf2
  
Line 14: Line 14:
 ==== Why do we need PBKDF2? ==== ==== Why do we need PBKDF2? ====
  
-PBKDF2 is defined in [[http://www.ietf.org/rfc/rfc2898.txt|RFC2898]] as a method for implementing password base cryptographic needs. These needs can include password storage, password derivation into a key (for encryption) or secure signatures.  Additionally, it's [[http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf|NIST Recommended]] for password storage.+PBKDF2 is defined in [[http://www.ietf.org/rfc/rfc2898.txt|RFC2898]] as a method for implementing password based cryptographic needs. These needs can include password storage, password derivation into a key (for encryption) or secure signatures.  Additionally, it's [[http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf|NIST Recommended]] for password storage.
  
 Adding a core implementation of the PBKDF2 algorithm will enable PHP projects to utilize a fast implementation of the algorithm, putting them on a more level ground for attackers. Since the C implementation is more efficient, more rounds can be computed for the same computational cost compared to a PHP land implementation.  This enables higher iteration counts to be used, providing more security with less impact to the overall performance of the application. Adding a core implementation of the PBKDF2 algorithm will enable PHP projects to utilize a fast implementation of the algorithm, putting them on a more level ground for attackers. Since the C implementation is more efficient, more rounds can be computed for the same computational cost compared to a PHP land implementation.  This enables higher iteration counts to be used, providing more security with less impact to the overall performance of the application.
Line 28: Line 28:
   * Blackberry Backup Encryption   * Blackberry Backup Encryption
   * Django Python Framework   * Django Python Framework
 +
 +===== Recommended Parameters For PBKDF2 =====
 +
 +==== $algo ====
 +
 +The way hash_pbkdf2 is written, any currently supported hash_algos() algorithm can be used as the base for the algorithm. This means that it's up to the developer to choose the appropriate algorithm to use when using the function. Here are a few of the popular algorithms and some recomendations around them. It should be noted that any cryptographic hash algorithm that's supported can be used successfully with PBKDF2 (**CRC32** is *not* cryptographic, therefore it should not be used).
 +
 +  - **SHA512** - This is currently one of the strongest algorithms available in PHP. It makes a good primitive for *hash_pbkdf2*
 +  - **SHA256** - This is also plenty strong enough for use as the basis for PBKDF2.
 +
 +A note on other popular algorithms: **SHA1** and **MD5** - Both are actually strong enough for effective use in PBKDF2. The reason is that the known attack vectors against the algorithm require knowledge of the input string being hashed. Therefore, an iterated algorithm such as PBKDF2 will be immune to the known attack vectors. That means it's **OK** to use for this task. With that said, the recommended approach is to use **SHA512** or **SHA256** instead, as the base algorithms are stronger. But it's not necessarily *bad* to use **SHA1** or **MD5**.
 +
 +==== $salt ====
 +
 +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.
 +
 +==== $iterations ====
 +
 +The iterations parameter provides the ability to *tune* the algorithm for different servers and needs. For most web uses, a minimum value of *1000* is recommended. However, as hardware varies greatly, testing should be done to find an iteration count that yields a function runtime of between 0.1 and 0.5 seconds (depending again on application). On higher end servers, this can be as much as 20,000 to 50,000 iterations (also depending on the hash algo used).
 +
 +It's better to use the highest iteration count possible, as it will only increase the resistance to brute forcing.
 +
 +==== $length ====
 +
 +The length parameter indicates the length of the returned key. The default value for length is the length of the hash algo's output. However, this can be increased or decreased as necessary. For example, if you're using PBKDF2 to generate a password-based key for use in an encryption routine such as RIJNDAEL 256, which expects a 256 bit key, you would want to pass the length parameter as 256/8 (to get the byte length), and set *$raw_output* to *true*. 
 +
 +==== $raw_output ====
 +
 +This parameter behaves just like the other *hash_* functions. If set to *true*, the function will return a binary string (chr 0-255). If set to *false*, the function will hex encode the result prior to returning it.
 +
 +===== Example =====
 +
 +Let's say you wanted to encrypt a file using a password. The password shouldn't be applied directly to the encryption function, but should be derived first.
 +
 +<file php encryption.php>
 +<?php
 +$password = "foo";
 +$data = "testing this out";
 +$salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
 +$key = hash_pbkdf2("sha512", $password, $salt, 5000, 16, true);
 +// $key will be full-byte 0-255 data
 +
 +$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
 +
 +$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
 +?>
 +</file>
 +
 +Or for storing passwords (BCrypt is recommended, but there are use-cases for PBKDF2, such as when NIST compliance is mandated):
 +<file php password.php>
 +<?php
 +$password = "foo";
 +$salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
 +$hash = hash_pbkdf2("sha512", $password, $salt, 5000, 32);
 +
 +// $hash will be a hex encoded string
 +?>
 +</file>
 +
  
 ===== Proposal and Patch ===== ===== Proposal and Patch =====
Line 37: Line 96:
 The patch is available as a [[https://github.com/php/php-src/pull/105|pull request]] to trunk. The patch is available as a [[https://github.com/php/php-src/pull/105|pull request]] to trunk.
  
-==== A Note On 5.4 ====+This RFC intends to add this functionality to master (5.5) only. 
 + 
 +===== Vote ===== 
 + 
 +Vote begins on 2012/07/02 and ends on 2012/07/09.  This vote is to include the new function in master only (5.5).
  
-The current pull request targets trunk, as per process. However, this patch only adds a single addition public API (hash_pbkdf2 as a PHP function). Therefore, it does not violate the rule against API changes in a point release. As such, it would be a candidate for inclusion in 5.4.x, if so desired.+<doodle  
 +title="rfc/hash_pbkdf2" auth="user" voteType="multi" closed="True"> 
 +   * Yes? 
 +   * No? 
 +</doodle>
  
 ===== More about PBKDF2 ===== ===== More about PBKDF2 =====
Line 50: Line 117:
 ===== Changelog ===== ===== Changelog =====
   * 0.1 - Initial Version   * 0.1 - Initial Version
 +  * 0.2 - Proposed
 +  * 0.3 - Added Parameter Information
 +  * 0.4 - Reworded to target master only, removing 5.4 section
 +  * 1.0 - Moving to Accepted state
rfc/hash_pbkdf2.1339639187.txt.gz · Last modified: 2017/09/22 13:28 (external edit)