1 <?php 2 /** 3 * Copyright 2015-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file LICENSE for license information (LGPL). If you 6 * did not receive this file, see http://www.horde.org/licenses/lgpl21. 7 * 8 * @author Michael Slusarz <slusarz@horde.org> 9 * @category Horde 10 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 11 * @package Crypt_Blowfish 12 */ 13 14 /** 15 * PBKDF2 (Password-Based Key Derivation Function 2) implementation (RFC 16 * 2898; PKCS #5 v2.0). 17 * 18 * @author Michael Slusarz <slusarz@horde.org> 19 * @category Horde 20 * @copyright 2015-2017 Horde LLC 21 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 22 * @package Crypt_Blowfish 23 * @link https://defuse.ca/php-pbkdf2.htm pbkdf2 code released to the 24 * public domain. 25 */ 26 class Horde_Crypt_Blowfish_Pbkdf2 27 { 28 /** 29 * Hash algorithm used to create key. 30 * 31 * @var string 32 */ 33 public $hashAlgo; 34 35 /** 36 * Number of iterations to use. 37 * 38 * @var integer 39 */ 40 public $iterations; 41 42 /** 43 * Salt. 44 * 45 * @var string 46 */ 47 public $salt; 48 49 /** 50 * The derived key. 51 * 52 * @var string 53 */ 54 protected $_key; 55 56 /** 57 * Constructor. 58 * 59 * @param string $pass The password. 60 * @param string $key_length Length of the derived key (in bytes). 61 * @param array $opts Additional options: 62 * - algo: (string) Hash algorithm. 63 * - i_count: (integer) Iteration count. 64 * - salt: (string) The salt to use. 65 */ 66 public function __construct($pass, $key_length, array $opts = array()) 67 { 68 $this->iterations = isset($opts['i_count']) 69 ? $opts['i_count'] 70 : 16384; 71 72 if (($key_length <= 0) || ($this->iterations <= 0)) { 73 throw new InvalidArgumentException('Invalid arguments'); 74 } 75 76 $this->hashAlgo = isset($opts['algo']) 77 ? $opts['algo'] 78 : 'SHA256'; 79 80 /* Nice to have, but salt does not need to be cryptographically 81 * secure random value. */ 82 $this->salt = isset($opts['salt']) 83 ? $opts['salt'] 84 : (function_exists('openssl_random_pseudo_bytes') 85 ? openssl_random_pseudo_bytes($key_length) 86 : substr(hash('sha512', new Horde_Support_Randomid(), true), 0, $key_length)); 87 88 if (function_exists('hash_pbkdf2')) { 89 $this->_key = hash_pbkdf2( 90 $this->hashAlgo, 91 $pass, 92 $this->salt, 93 $this->iterations, 94 $key_length, 95 true 96 ); 97 return; 98 } 99 100 $hash_length = strlen(hash($this->hashAlgo, '', true)); 101 $block_count = ceil($key_length / $hash_length); 102 103 $hash = ''; 104 for ($i = 1; $i <= $block_count; ++$i) { 105 // $i encoded as 4 bytes, big endian. 106 $last = $this->salt . pack('N', $i); 107 for ($j = 0; $j < $this->iterations; $j++) { 108 $last = hash_hmac($this->hashAlgo, $last, $pass, true); 109 if ($j) { 110 $xorsum ^= $last; 111 } else { 112 $xorsum = $last; 113 } 114 } 115 $hash .= $xorsum; 116 } 117 118 $this->_key = substr($hash, 0, $key_length); 119 } 120 121 /** 122 */ 123 public function __toString() 124 { 125 return $this->_key; 126 } 127 128 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body