LDAPAccountManager/lam/lib/3rdParty/composer/pear-pear.horde.org/Horde_Crypt_Blowfish/Horde/Crypt/Blowfish/Pbkdf2.php

129 lines
3.4 KiB
PHP

<?php
/**
* Copyright 2015-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
*/
/**
* PBKDF2 (Password-Based Key Derivation Function 2) implementation (RFC
* 2898; PKCS #5 v2.0).
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2015-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt_Blowfish
* @link https://defuse.ca/php-pbkdf2.htm pbkdf2 code released to the
* public domain.
*/
class Horde_Crypt_Blowfish_Pbkdf2
{
/**
* Hash algorithm used to create key.
*
* @var string
*/
public $hashAlgo;
/**
* Number of iterations to use.
*
* @var integer
*/
public $iterations;
/**
* Salt.
*
* @var string
*/
public $salt;
/**
* The derived key.
*
* @var string
*/
protected $_key;
/**
* Constructor.
*
* @param string $pass The password.
* @param string $key_length Length of the derived key (in bytes).
* @param array $opts Additional options:
* - algo: (string) Hash algorithm.
* - i_count: (integer) Iteration count.
* - salt: (string) The salt to use.
*/
public function __construct($pass, $key_length, array $opts = array())
{
$this->iterations = isset($opts['i_count'])
? $opts['i_count']
: 16384;
if (($key_length <= 0) || ($this->iterations <= 0)) {
throw new InvalidArgumentException('Invalid arguments');
}
$this->hashAlgo = isset($opts['algo'])
? $opts['algo']
: 'SHA256';
/* Nice to have, but salt does not need to be cryptographically
* secure random value. */
$this->salt = isset($opts['salt'])
? $opts['salt']
: (function_exists('openssl_random_pseudo_bytes')
? openssl_random_pseudo_bytes($key_length)
: substr(hash('sha512', new Horde_Support_Randomid(), true), 0, $key_length));
if (function_exists('hash_pbkdf2')) {
$this->_key = hash_pbkdf2(
$this->hashAlgo,
$pass,
$this->salt,
$this->iterations,
$key_length,
true
);
return;
}
$hash_length = strlen(hash($this->hashAlgo, '', true));
$block_count = ceil($key_length / $hash_length);
$hash = '';
for ($i = 1; $i <= $block_count; ++$i) {
// $i encoded as 4 bytes, big endian.
$last = $this->salt . pack('N', $i);
for ($j = 0; $j < $this->iterations; $j++) {
$last = hash_hmac($this->hashAlgo, $last, $pass, true);
if ($j) {
$xorsum ^= $last;
} else {
$xorsum = $last;
}
}
$hash .= $xorsum;
}
$this->_key = substr($hash, 0, $key_length);
}
/**
*/
public function __toString()
{
return $this->_key;
}
}