File indexing completed on 2024-12-22 05:36:34
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Crypt 0017 * @subpackage Hmac 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * @see Zend_Crypt 0025 */ 0026 // require_once 'Zend/Crypt.php'; 0027 0028 /** 0029 * PHP implementation of the RFC 2104 Hash based Message Authentication Code 0030 * algorithm. 0031 * 0032 * @todo Patch for refactoring failed tests (key block sizes >80 using internal algo) 0033 * @todo Check if mhash() is a required alternative (will be PECL-only soon) 0034 * @category Zend 0035 * @package Zend_Crypt 0036 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0037 * @license http://framework.zend.com/license/new-bsd New BSD License 0038 */ 0039 class Zend_Crypt_Hmac extends Zend_Crypt 0040 { 0041 0042 /** 0043 * The key to use for the hash 0044 * 0045 * @var string 0046 */ 0047 protected static $_key = null; 0048 0049 /** 0050 * pack() format to be used for current hashing method 0051 * 0052 * @var string 0053 */ 0054 protected static $_packFormat = null; 0055 0056 /** 0057 * Hashing algorithm; can be the md5/sha1 functions or any algorithm name 0058 * listed in the output of PHP 5.1.2+ hash_algos(). 0059 * 0060 * @var string 0061 */ 0062 protected static $_hashAlgorithm = 'md5'; 0063 0064 /** 0065 * List of algorithms supported my mhash() 0066 * 0067 * @var array 0068 */ 0069 protected static $_supportedMhashAlgorithms = array('adler32',' crc32', 'crc32b', 'gost', 0070 'haval128', 'haval160', 'haval192', 'haval256', 'md4', 'md5', 'ripemd160', 0071 'sha1', 'sha256', 'tiger', 'tiger128', 'tiger160'); 0072 0073 /** 0074 * Constants representing the output mode of the hash algorithm 0075 */ 0076 const STRING = 'string'; 0077 const BINARY = 'binary'; 0078 0079 /** 0080 * Performs a HMAC computation given relevant details such as Key, Hashing 0081 * algorithm, the data to compute MAC of, and an output format of String, 0082 * Binary notation or BTWOC. 0083 * 0084 * @param string $key 0085 * @param string $hash 0086 * @param string $data 0087 * @param string $output 0088 * @throws Zend_Crypt_Hmac_Exception 0089 * @return string 0090 */ 0091 public static function compute($key, $hash, $data, $output = self::STRING) 0092 { 0093 // set the key 0094 if (!isset($key) || empty($key)) { 0095 // require_once 'Zend/Crypt/Hmac/Exception.php'; 0096 throw new Zend_Crypt_Hmac_Exception('provided key is null or empty'); 0097 } 0098 self::$_key = $key; 0099 0100 // set the hash 0101 self::_setHashAlgorithm($hash); 0102 0103 // perform hashing and return 0104 return self::_hash($data, $output); 0105 } 0106 0107 /** 0108 * Setter for the hash method. 0109 * 0110 * @param string $hash 0111 * @throws Zend_Crypt_Hmac_Exception 0112 * @return Zend_Crypt_Hmac 0113 */ 0114 protected static function _setHashAlgorithm($hash) 0115 { 0116 if (!isset($hash) || empty($hash)) { 0117 // require_once 'Zend/Crypt/Hmac/Exception.php'; 0118 throw new Zend_Crypt_Hmac_Exception('provided hash string is null or empty'); 0119 } 0120 0121 $hash = strtolower($hash); 0122 $hashSupported = false; 0123 0124 if (function_exists('hash_algos') && in_array($hash, hash_algos())) { 0125 $hashSupported = true; 0126 } 0127 0128 if ($hashSupported === false && function_exists('mhash') && in_array($hash, self::$_supportedAlgosMhash)) { 0129 $hashSupported = true; 0130 } 0131 0132 if ($hashSupported === false) { 0133 // require_once 'Zend/Crypt/Hmac/Exception.php'; 0134 throw new Zend_Crypt_Hmac_Exception('hash algorithm provided is not supported on this PHP installation; please enable the hash or mhash extensions'); 0135 } 0136 self::$_hashAlgorithm = $hash; 0137 } 0138 0139 /** 0140 * Perform HMAC and return the keyed data 0141 * 0142 * @param string $data 0143 * @param string $output 0144 * @param bool $internal Option to not use hash() functions for testing 0145 * @return string 0146 */ 0147 protected static function _hash($data, $output = self::STRING, $internal = false) 0148 { 0149 if (function_exists('hash_hmac')) { 0150 if ($output == self::BINARY) { 0151 return hash_hmac(self::$_hashAlgorithm, $data, self::$_key, true); 0152 } 0153 return hash_hmac(self::$_hashAlgorithm, $data, self::$_key); 0154 } 0155 0156 if (function_exists('mhash')) { 0157 if ($output == self::BINARY) { 0158 return mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key); 0159 } 0160 $bin = mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key); 0161 return bin2hex($bin); 0162 } 0163 } 0164 0165 /** 0166 * Since MHASH accepts an integer constant representing the hash algorithm 0167 * we need to make a small detour to get the correct integer matching our 0168 * algorithm's name. 0169 * 0170 * @param string $hashAlgorithm 0171 * @return integer 0172 */ 0173 protected static function _getMhashDefinition($hashAlgorithm) 0174 { 0175 for ($i = 0; $i <= mhash_count(); $i++) 0176 { 0177 $types[mhash_get_hash_name($i)] = $i; 0178 } 0179 return $types[strtoupper($hashAlgorithm)]; 0180 } 0181 0182 }