Skip to content

Instantly share code, notes, and snippets.

@labeneator
Last active December 18, 2015 03:19
Show Gist options
  • Save labeneator/5717217 to your computer and use it in GitHub Desktop.
Save labeneator/5717217 to your computer and use it in GitHub Desktop.
/*
# 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