Last active
December 18, 2015 03:19
-
-
Save labeneator/5717217 to your computer and use it in GitHub Desktop.
pbkdf in pure php using the modules provided by zend .
See http://framework.zend.com/manual/2.1/en/modules/zend.crypt.key.derivation.html#scrypt-adapter
and
https://github.com/ezimuel/zf2/tree/f259efd742d8ed8d904db748846e43e417f5a807/library/Zend/Crypt/Key/Derivation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
# php -v | |
PHP 5.3.15 with Suhosin-Patch (cli) (built: Jul 31 2012 14:49:18) | |
Copyright (c) 1997-2012 The PHP Group | |
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies | |
Takes 0.6 seconds per hash at 100000 rounds | |
# time php test.php | |
Original password: password | |
Salt (hex) : 8454780bed43 | |
Derived key (hex) using 100000 rounds: 2d0dd0f9649ca1c040a8f62e0e720c2b | |
real 0m0.607s | |
user 0m0.595s | |
sys 0m0.010s | |
# cat test.php | |
*/ | |
<?php | |
include "Pbkdf2.php"; | |
#use ZendMath\Rand; | |
$pass = 'password'; | |
#$salt = Rand::getBytes(strlen($pass), true); | |
$salt = openssl_random_pseudo_bytes(6); | |
$rounds = 100000; | |
$key = Pbkdf2::calc('sha256', $pass, $salt, $rounds, strlen($pass)*2); | |
printf ("Original password: %s\n", $pass); | |
printf ("Salt (hex) : %s\n", bin2hex($salt)); | |
printf ("Derived key (hex) using %d rounds: %s\n", $rounds, bin2hex($key)); | |
?> | |
/* | |
* Dependencies from zend | |
* cat Pbkdf2.php | |
*/ | |
<?php | |
/** | |
* Zend Framework (http://framework.zend.com/) | |
* | |
* @link http://github.com/zendframework/zf2 for the canonical source repository | |
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | |
* @license http://framework.zend.com/license/new-bsd New BSD License | |
* @package Zend_Crypt | |
*/ | |
//namespace KeyDerivation; | |
include "Hmac.php"; | |
/** | |
* PKCS #5 v2.0 standard RFC 2898 | |
* | |
* @category Zend | |
* @package Zend_Crypt | |
*/ | |
class Pbkdf2 | |
{ | |
/** | |
* Generate the new key | |
* | |
* @param string $hash The hash algorithm to be used by HMAC | |
* @param string $password The source password/key | |
* @param string $salt | |
* @param integer $iterations The number of iterations | |
* @param integer $length The output size | |
* @throws Exception\InvalidArgumentException | |
* @return string | |
*/ | |
public static function calc($hash, $password, $salt, $iterations, $length) | |
{ | |
if (!in_array($hash, Hmac::getSupportedAlgorithms())) { | |
throw new Exception\InvalidArgumentException("The hash algorihtm $hash is not supported by " . __CLASS__); | |
} | |
$num = ceil($length / Hmac::getOutputSize($hash, Hmac::OUTPUT_BINARY)); | |
$result = ''; | |
for ($block = 1; $block <= $num; $block++) { | |
$hmac = Hmac::compute($password, $hash, $salt . pack('N', $block), Hmac::OUTPUT_BINARY); | |
$mix = $hmac; | |
for ($i = 1; $i < $iterations; $i++) { | |
$hmac = Hmac::compute($password, $hash, $hmac, Hmac::OUTPUT_BINARY); | |
$mix ^= $hmac; | |
} | |
$result .= $mix; | |
} | |
return substr($result, 0, $length); | |
} | |
} | |
/* | |
* Dependencies from zend | |
* cat Hmac.php | |
*/ | |
<?php | |
/** | |
* Zend Framework (http://framework.zend.com/) | |
* | |
* @link http://github.com/zendframework/zf2 for the canonical source repository | |
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | |
* @license http://framework.zend.com/license/new-bsd New BSD License | |
* @package Zend_Crypt | |
*/ | |
//namespace Zend\Crypt; | |
/** | |
* PHP implementation of the RFC 2104 Hash based Message Authentication Code | |
* | |
* @category Zend | |
* @package Zend_Crypt | |
*/ | |
class Hmac | |
{ | |
const OUTPUT_STRING = 'string'; | |
const OUTPUT_BINARY = 'binary'; | |
/** | |
* List of hash algorithms supported | |
* | |
* @var array | |
*/ | |
protected static $supportedAlgorithms = array(); | |
/** | |
* Performs a HMAC computation given relevant details such as Key, Hashing | |
* algorithm, the data to compute MAC of, and an output format of String, | |
* or Binary. | |
* | |
* @param string $key | |
* @param string $hash | |
* @param string $data | |
* @param string $output | |
* @throws Exception\InvalidArgumentException | |
* @return string | |
*/ | |
public static function compute($key, $hash, $data, $output = self::OUTPUT_STRING) | |
{ | |
$hash = strtolower($hash); | |
if (!self::isSupported($hash)) { | |
throw new Exception\InvalidArgumentException( | |
"Hash algorithm is not supported on this PHP installation; provided '{$hash}'" | |
); | |
} | |
$output = ($output === self::OUTPUT_BINARY); | |
return hash_hmac($hash, $data, $key, $output); | |
} | |
/** | |
* Get the output size according to the hash algorithm and the output format | |
* | |
* @param string $hash | |
* @param string $output | |
* @return integer | |
*/ | |
public static function getOutputSize($hash, $output = self::OUTPUT_STRING) | |
{ | |
return strlen(self::compute('key', $hash, 'data', $output)); | |
} | |
/** | |
* Get the supported algorithm | |
* | |
* @return array | |
*/ | |
public static function getSupportedAlgorithms() | |
{ | |
if (empty(self::$supportedAlgorithms)) { | |
self::$supportedAlgorithms = hash_algos(); | |
} | |
return self::$supportedAlgorithms; | |
} | |
/** | |
* Is the hash algorithm supported? | |
* | |
* @param string $algo | |
* @return boolean | |
*/ | |
public static function isSupported($algo) | |
{ | |
return in_array($algo, self::getSupportedAlgorithms()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment