Guest User

PBKDF2.class.php

a guest
Jul 13th, 2013
2,841
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.     /**
  3.      * Password hashing with PBKDF2.
  4.      * (modified to use the native php function if available)
  5.      * Based on the pure PHP implementation of PBKDF2 which can be found on:
  6.      * https://defuse.ca/php-pbkdf2.htm
  7.      *
  8.      * @author havoc AT defuse.ca (www: https://defuse.ca/php-pbkdf2.htm)
  9.      * @author TheBlintOne
  10.      *
  11.      * @license Public Domain (so feel free to use it): http://en.wikipedia.org/wiki/Public_domain
  12.      */
  13.  
  14.     /**
  15.      * Class to encapsulate the PBKDF2 functions
  16.      *
  17.      * @author havoc AT defuse.ca (www: https://defuse.ca/php-pbkdf2.htm)
  18.      * @author TheBlintOne
  19.      */
  20.     class PBKDF2
  21.     {
  22.         // These constants may be changed without breaking existing hashes.
  23.         const PBKDF2_HASH_ALGORITHM = "sha256";
  24.         const PBKDF2_ITERATIONS = 1000;
  25.         const PBKDF2_SALT_BYTES = 24;
  26.         const PBKDF2_HASH_BYTES = 24;
  27.  
  28.         const HASH_SECTIONS = 4;
  29.         const HASH_ALGORITHM_INDEX = 0;
  30.         const HASH_ITERATION_INDEX = 1;
  31.         const HASH_SALT_INDEX = 2;
  32.         const HASH_PBKDF2_INDEX = 3;
  33.  
  34.         /**
  35.          * Creates a hash for the given password
  36.          *
  37.          * @param string $password    the password to hash
  38.          * @return string             the hashed password in format "algorithm:iterations:salt:hash"
  39.          */
  40.         public function create_hash( $password )
  41.         {
  42.             $salt = base64_encode( mcrypt_create_iv( PBKDF2::PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM ) );
  43.             return PBKDF2::PBKDF2_HASH_ALGORITHM . ":" . PBKDF2::PBKDF2_ITERATIONS . ":" .  $salt . ":" .
  44.                 base64_encode( $this->hash(
  45.                     PBKDF2::PBKDF2_HASH_ALGORITHM,
  46.                     $password,
  47.                     $salt,
  48.                     PBKDF2::PBKDF2_ITERATIONS,
  49.                     PBKDF2::PBKDF2_HASH_BYTES,
  50.                     true
  51.                 ) );
  52.         }
  53.  
  54.         /**
  55.          * Checks if the given password matches the given hash created by PBKDF::create_hash( string )
  56.          *
  57.          * @param string $password     the password to check
  58.          * @param string $good_hash    the hash which should be match the password
  59.          * @return boolean             true if $password and $good_hash match, false otherwise
  60.          *
  61.          * @see PBKDF2::create_hash
  62.          */
  63.         public function validate_password( $password, $good_hash )
  64.         {
  65.             $params = explode( ":", $good_hash );
  66.             if( count( $params ) < HASH_SECTIONS )
  67.                return false;
  68.             $pbkdf2 = base64_decode( $params[ PBKDF2::HASH_PBKDF2_INDEX ] );
  69.             return slow_equals(
  70.                 $pbkdf2,
  71.                 $this->hash(
  72.                     $params[ PBKDF2::HASH_ALGORITHM_INDEX ],
  73.                     $password,
  74.                     $params[ PBKDF2::HASH_SALT_INDEX ],
  75.                     (int)$params[ PBKDF2::HASH_ITERATION_INDEX ],
  76.                     strlen( $pbkdf2 ),
  77.                     true
  78.                 )
  79.             );
  80.         }
  81.  
  82.         /**
  83.          * Compares two strings $a and $b in length-constant time
  84.          *
  85.          * @param string $a    the first string
  86.          * @param string $b    the second string
  87.          * @return boolean     true if they are equal, false otherwise
  88.          */
  89.         public function slow_equals( $a, $b )
  90.         {
  91.             $diff = strlen( $a ) ^ strlen( $b );
  92.             for( $i = 0; $i < strlen( $a ) && $i < strlen( $b ); $i++ )
  93.             {
  94.                 $diff |= ord( $a[ $i ] ) ^ ord( $b[ $i ] );
  95.             }
  96.             return $diff === 0;
  97.         }
  98.  
  99.         /**
  100.          * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
  101.          *
  102.          * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
  103.          *
  104.          * This implementation of PBKDF2 was originally created by https://defuse.ca
  105.          * With improvements by http://www.variations-of-shadow.com
  106.          * Added support for the native PHP implementation by TheBlintOne
  107.          *
  108.          * @param string $algorithm                                 the hash algorithm to use. Recommended: SHA256
  109.          * @param string $password                                  the Password
  110.          * @param string $salt                                      a salt that is unique to the password
  111.          * @param int $count                                        iteration count. Higher is better, but slower. Recommended: At least 1000
  112.          * @param int $key_length                                   the length of the derived key in bytes
  113.          * @param boolean $raw_output [optional] (default false)    if true, the key is returned in raw binary format. Hex encoded otherwise
  114.          * @return string                                           a $key_length-byte key derived from the password and salt,
  115.          *                                                          depending on $raw_output this is either Hex encoded or raw binary
  116.          * @throws Exception                                        if the hash algorithm are not found or if there are invalid parameters
  117.          */
  118.         public function hash( $algorithm, $password, $salt, $count, $key_length, $raw_output = false )
  119.         {
  120.             $algorithm = strtolower( $algorithm );
  121.             if( !in_array( $algorithm, hash_algos() , true ) )
  122.                 throw new Exception( 'PBKDF2 ERROR: Invalid hash algorithm.' );
  123.             if( $count <= 0 || $key_length <= 0 )
  124.                 throw new Exception( 'PBKDF2 ERROR: Invalid parameters.' );
  125.  
  126.             // use the native implementation of the algorithm if available
  127.             if( function_exists( "hash_pbkdf2" ) )
  128.             {
  129.                 return hash_pbkdf2( $algorithm, $password, $salt, $count, $key_length, $raw_output );
  130.             }
  131.  
  132.             $hash_length = strlen( hash( $algorithm, "", true ) );
  133.             $block_count = ceil( $key_length / $hash_length );
  134.  
  135.             $output = "";
  136.             for( $i = 1; $i <= $block_count; $i++ )
  137.             {
  138.                 // $i encoded as 4 bytes, big endian.
  139.                 $last = $salt . pack( "N", $i );
  140.                 // first iteration
  141.                 $last = $xorsum = hash_hmac( $algorithm, $last, $password, true );
  142.                 // perform the other $count - 1 iterations
  143.                 for( $j = 1; $j < $count; $j++ )
  144.                 {
  145.                     $xorsum ^= ( $last = hash_hmac( $algorithm, $last, $password, true ) );
  146.                 }
  147.                 $output .= $xorsum;
  148.             }
  149.  
  150.             if( $raw_output )
  151.                 return substr( $output, 0, $key_length );
  152.             else
  153.                 return bin2hex( substr( $output, 0, $key_length ) );
  154.         }
  155.     }
  156. ?>
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×