|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Crypt |
|
17 * @subpackage Hmac |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Hmac.php 20096 2010-01-06 02:05:09Z bkarwin $ |
|
21 */ |
|
22 |
|
23 /** |
|
24 * @see Zend_Crypt |
|
25 */ |
|
26 require_once 'Zend/Crypt.php'; |
|
27 |
|
28 /** |
|
29 * PHP implementation of the RFC 2104 Hash based Message Authentication Code |
|
30 * algorithm. |
|
31 * |
|
32 * @todo Patch for refactoring failed tests (key block sizes >80 using internal algo) |
|
33 * @todo Check if mhash() is a required alternative (will be PECL-only soon) |
|
34 * @category Zend |
|
35 * @package Zend_Crypt |
|
36 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
37 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
38 */ |
|
39 class Zend_Crypt_Hmac extends Zend_Crypt |
|
40 { |
|
41 |
|
42 /** |
|
43 * The key to use for the hash |
|
44 * |
|
45 * @var string |
|
46 */ |
|
47 protected static $_key = null; |
|
48 |
|
49 /** |
|
50 * pack() format to be used for current hashing method |
|
51 * |
|
52 * @var string |
|
53 */ |
|
54 protected static $_packFormat = null; |
|
55 |
|
56 /** |
|
57 * Hashing algorithm; can be the md5/sha1 functions or any algorithm name |
|
58 * listed in the output of PHP 5.1.2+ hash_algos(). |
|
59 * |
|
60 * @var string |
|
61 */ |
|
62 protected static $_hashAlgorithm = 'md5'; |
|
63 |
|
64 /** |
|
65 * List of algorithms supported my mhash() |
|
66 * |
|
67 * @var array |
|
68 */ |
|
69 protected static $_supportedMhashAlgorithms = array('adler32',' crc32', 'crc32b', 'gost', |
|
70 'haval128', 'haval160', 'haval192', 'haval256', 'md4', 'md5', 'ripemd160', |
|
71 'sha1', 'sha256', 'tiger', 'tiger128', 'tiger160'); |
|
72 |
|
73 /** |
|
74 * Constants representing the output mode of the hash algorithm |
|
75 */ |
|
76 const STRING = 'string'; |
|
77 const BINARY = 'binary'; |
|
78 |
|
79 /** |
|
80 * Performs a HMAC computation given relevant details such as Key, Hashing |
|
81 * algorithm, the data to compute MAC of, and an output format of String, |
|
82 * Binary notation or BTWOC. |
|
83 * |
|
84 * @param string $key |
|
85 * @param string $hash |
|
86 * @param string $data |
|
87 * @param string $output |
|
88 * @param boolean $internal |
|
89 * @return string |
|
90 */ |
|
91 public static function compute($key, $hash, $data, $output = self::STRING) |
|
92 { |
|
93 // set the key |
|
94 if (!isset($key) || empty($key)) { |
|
95 require_once 'Zend/Crypt/Hmac/Exception.php'; |
|
96 throw new Zend_Crypt_Hmac_Exception('provided key is null or empty'); |
|
97 } |
|
98 self::$_key = $key; |
|
99 |
|
100 // set the hash |
|
101 self::_setHashAlgorithm($hash); |
|
102 |
|
103 // perform hashing and return |
|
104 return self::_hash($data, $output); |
|
105 } |
|
106 |
|
107 /** |
|
108 * Setter for the hash method. |
|
109 * |
|
110 * @param string $hash |
|
111 * @return Zend_Crypt_Hmac |
|
112 */ |
|
113 protected static function _setHashAlgorithm($hash) |
|
114 { |
|
115 if (!isset($hash) || empty($hash)) { |
|
116 require_once 'Zend/Crypt/Hmac/Exception.php'; |
|
117 throw new Zend_Crypt_Hmac_Exception('provided hash string is null or empty'); |
|
118 } |
|
119 |
|
120 $hash = strtolower($hash); |
|
121 $hashSupported = false; |
|
122 |
|
123 if (function_exists('hash_algos') && in_array($hash, hash_algos())) { |
|
124 $hashSupported = true; |
|
125 } |
|
126 |
|
127 if ($hashSupported === false && function_exists('mhash') && in_array($hash, self::$_supportedAlgosMhash)) { |
|
128 $hashSupported = true; |
|
129 } |
|
130 |
|
131 if ($hashSupported === false) { |
|
132 require_once 'Zend/Crypt/Hmac/Exception.php'; |
|
133 throw new Zend_Crypt_Hmac_Exception('hash algorithm provided is not supported on this PHP installation; please enable the hash or mhash extensions'); |
|
134 } |
|
135 self::$_hashAlgorithm = $hash; |
|
136 } |
|
137 |
|
138 /** |
|
139 * Perform HMAC and return the keyed data |
|
140 * |
|
141 * @param string $data |
|
142 * @param string $output |
|
143 * @param bool $internal Option to not use hash() functions for testing |
|
144 * @return string |
|
145 */ |
|
146 protected static function _hash($data, $output = self::STRING, $internal = false) |
|
147 { |
|
148 if (function_exists('hash_hmac')) { |
|
149 if ($output == self::BINARY) { |
|
150 return hash_hmac(self::$_hashAlgorithm, $data, self::$_key, 1); |
|
151 } |
|
152 return hash_hmac(self::$_hashAlgorithm, $data, self::$_key); |
|
153 } |
|
154 |
|
155 if (function_exists('mhash')) { |
|
156 if ($output == self::BINARY) { |
|
157 return mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key); |
|
158 } |
|
159 $bin = mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key); |
|
160 return bin2hex($bin); |
|
161 } |
|
162 } |
|
163 |
|
164 /** |
|
165 * Since MHASH accepts an integer constant representing the hash algorithm |
|
166 * we need to make a small detour to get the correct integer matching our |
|
167 * algorithm's name. |
|
168 * |
|
169 * @param string $hashAlgorithm |
|
170 * @return integer |
|
171 */ |
|
172 protected static function _getMhashDefinition($hashAlgorithm) |
|
173 { |
|
174 for ($i = 0; $i <= mhash_count(); $i++) |
|
175 { |
|
176 $types[mhash_get_hash_name($i)] = $i; |
|
177 } |
|
178 return $types[strtoupper($hashAlgorithm)]; |
|
179 } |
|
180 |
|
181 } |