Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * Implementation of the Hashed Message Authentication Code algorithm with
4
 * support for a wide range of hashing algorithms available using either of
5
 * the "hash" or "mhash" extensions, or the native md5() and sha1() functions.
6
 *
7
 * PHP version 5
8
 *
9
 * LICENSE:
10
 *
11
 * Copyright (c) 2005-2007, Pádraic Brady <padraic.brady@yahoo.com>
12
 * All rights reserved.
13
 *
14
 * Redistribution and use in source and binary forms, with or without
15
 * modification, are permitted provided that the following conditions
16
 * are met:
17
 *
18
 *    * Redistributions of source code must retain the above copyright
19
 *      notice, this list of conditions and the following disclaimer.
20
 *    * Redistributions in binary form must reproduce the above copyright
21
 *      notice, this list of conditions and the following disclaimer in the
22
 *      documentation and/or other materials provided with the distribution.
23
 *    * The name of the author may not be used to endorse or promote products
24
 *      derived from this software without specific prior written permission.
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
27
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
28
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
34
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
 *
38
 * @category    Encryption
39
 * @package     Crypt_HMAC2
40
 * @author      Pádraic Brady <padraic.brady@yahoo.com>
41
 * @license     http://opensource.org/licenses/bsd-license.php New BSD License
42
 * @version     $Id: HMAC2.php 965 2012-02-28 07:37:41Z tiefland $
43
 * @link        http://
44
 */
45
 
46
/**
47
 * Crypt_HMAC2 class
48
 *
49
 * Example usage:
50
 *      $key = str_repeat("\xaa", 20); // insecure key only for example
51
 *      $data = "Hello World!";
52
 *      $hmac = new Crypt_HMAC2($key, 'SHA256');
53
 *      $hmacHash = $hmac->hash($data);
54
 *
55
 *      Supported hashing algorithms are limited by your PHP version access
56
 *      to the hash, mhash extensions and supported native functions like
57
 *      md5() and sha1().
58
 *
59
 *      To obtain raw binary output, set the optional second parameter of
60
 *      Crypt_HMAC2::hash() to Crypt_HMAC2::BINARY.
61
 *
62
 *      $hmacRawHash = $hmac->hash($data, Crypt_HMAC2::BINARY);
63
 *
64
 * @category   Encryption
65
 * @package    Crypt_HMAC2
66
 * @author     Pádraic Brady <padraic.brady@yahoo.com>
67
 * @copyright  2005-2007 Pádraic Brady
68
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
69
 * @link       http://
70
 * @version    @package_version@
71
 * @access     public
72
 */
73
class Crypt_HMAC2
74
{
75
 
76
    /**
77
     * The key to use for the hash
78
     *
79
     * @var string
80
     */
81
    protected $_key = null;
82
 
83
    /**
84
     * pack() format to be used for current hashing method
85
     *
86
     * @var string
87
     */
88
    protected $_packFormat = null;
89
 
90
    /**
91
     * Hashing algorithm; can be the md5/sha1 functions or any algorithm name
92
     * listed in the output of PHP 5.1.2+ hash_algos().
93
     *
94
     * @var string
95
     */
96
    protected $_hashAlgorithm = 'md5';
97
 
98
    /**
99
     * Supported direct hashing functions in PHP
100
     *
101
     * @var array
102
     */
103
    protected $_supportedHashNativeFunctions = array(
104
        'md5',
105
        'sha1',
106
    );
107
 
108
    /**
109
     * List of hash pack formats for each hashing algorithm supported.
110
     * Only required when hash or mhash are not available, and we are
111
     * using either md5() or sha1().
112
     *
113
     * @var array
114
     */
115
    protected $_hashPackFormats = array(
116
        'md5'        => 'H32',
117
        'sha1'       => 'H40'
118
    );
119
 
120
    /**
121
     * List of algorithms supported my mhash()
122
     *
123
     * @var array
124
     */
125
    protected $_supportedMhashAlgorithms = array('adler32',' crc32', 'crc32b', 'gost',
126
            'haval128', 'haval160', 'haval192', 'haval256', 'md4', 'md5', 'ripemd160',
127
            'sha1', 'sha256', 'tiger', 'tiger128', 'tiger160');
128
 
129
    /**
130
     * Constants representing the output mode of the hash algorithm
131
     */
132
    const STRING = 'string';
133
    const BINARY = 'binary';
134
 
135
    /**
136
     * Constructor; optionally set Key and Hash at this point
137
     *
138
     * @param string $key
139
     * @param string $hash
140
     */
141
    public function __construct($key = null, $hash = null)
142
    {
143
        if (!is_null($key)) {
144
            $this->setKey($key);
145
        }
146
        if (!is_null($hash)) {
147
            $this->setHashAlgorithm($hash);
148
        }
149
    }
150
 
151
    /**
152
     * Set the key to use when hashing
153
     *
154
     * @param string $key
155
     * @return Crypt_HMAC2
156
     */
157
    public function setKey($key)
158
    {
159
        if (!isset($key) || empty($key)) {
160
            require_once 'Crypt/HMAC2/Exception.php';
161
            throw new Crypt_HMAC2_Exception('provided key is null or empty');
162
        }
163
        $this->_key = $key;
164
        return $this;
165
    }
166
 
167
    /**
168
     * Getter to return the currently set key
169
     *
170
     * @return string
171
     */
172
    public function getKey()
173
    {
174
        if (is_null($this->_key)) {
175
            require_once 'Crypt/HMAC2/Exception.php';
176
            throw new Crypt_HMAC2_Exception('key has not yet been set');
177
        }
178
        return $this->_key;
179
    }
180
 
181
    /**
182
     * Setter for the hash method. Supports md5() and sha1() functions, and if
183
     * available the hashing algorithms supported by the hash() PHP5 function or
184
     * the mhash extension.
185
     *
186
     * Since they are so many varied HMAC methods in PHP these days this method
187
     * does a lot of checking to figure out what's available and not.
188
     *
189
     * @param string $hash
190
     * @return Crypt_HMAC2
191
     */
192
    public function setHashAlgorithm($hash)
193
    {
194
        if (!isset($hash) || empty($hash)) {
195
            require_once 'Crypt/HMAC2/Exception.php';
196
            throw new Crypt_HMAC2_Exception('provided hash string is null or empty');
197
        }
198
        $hash = strtolower($hash);
199
        $hashSupported = false;
200
        if (function_exists('hash_algos') && in_array($hash, hash_algos())) {
201
            $hashSupported = true;
202
        }
203
        if ($hashSupported === false && function_exists('mhash') && in_array($hash, $this->_supportedMhashAlgorithms)) {
204
            $hashSupported = true;
205
        }
206
        if ($hashSupported === false && in_array($hash, $this->_supportedHashNativeFunctions) && in_array($hash, array_keys($this->_hashPackFormats))) {
207
            $this->_packFormat = $this->_hashPackFormats[$hash];
208
            $hashSupported = true;
209
        }
210
        if ($hashSupported === false) {
211
            require_once 'Crypt/HMAC2/Exception.php';
212
            throw new Crypt_HMAC2_Exception('hash algorithm provided is not supported on this PHP instance; please enable the hash or mhash extensions');
213
        }
214
        $this->_hashAlgorithm = $hash;
215
        return $this;
216
    }
217
 
218
    /**
219
     * Return the current hashing algorithm
220
     *
221
     * @return string
222
     */
223
    public function getHashAlgorithm()
224
    {
225
        return $this->_hashAlgorithm;
226
    }
227
 
228
    /**
229
     * Perform HMAC and return the keyed data
230
     *
231
     * @param string $data
232
     * @param bool $internal Option to not use hash() functions for testing
233
     * @return string
234
     */
235
    public function hash($data, $output = self::STRING, $internal = false)
236
    {
237
        if (function_exists('hash_hmac') && $internal === false) {
238
            if ($output == self::BINARY) {
239
                return hash_hmac($this->getHashAlgorithm(), $data, $this->getKey(), 1);
240
            }
241
            return hash_hmac($this->getHashAlgorithm(), $data, $this->getKey());
242
        }
243
 
244
        if (function_exists('mhash') && $internal === false) {
245
            if ($output == self::BINARY) {
246
                return mhash($this->_getMhashDefinition($this->getHashAlgorithm()), $data, $this->getKey());
247
            }
248
            $bin = mhash($this->_getMhashDefinition($this->getHashAlgorithm()), $data, $this->getKey());
249
            return bin2hex($bin);
250
        }
251
 
252
        // last ditch effort for MD5 and SHA1 only
253
        $key = $this->getKey();
254
        $hash = $this->getHashAlgorithm();
255
 
256
        if (strlen($key) < 64) {
257
            $key = str_pad($key, 64, chr(0));
258
        } elseif (strlen($key) > 64) {
259
           $key =  pack($this->_packFormat, $this->_digest($hash, $key, $output));
260
        }
261
        $padInner = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
262
        $padOuter = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
263
 
264
        return $this->_digest($hash, $padOuter . pack($this->_packFormat, $this->_digest($hash, $padInner . $data, $output)), $output);
265
    }
266
 
267
    /**
268
     * Method of working around the inability to use mhash constants; this
269
     * will locate the Constant value of any support Hashing algorithm named
270
     * in the string parameter.
271
     *
272
     * @param string $hashAlgorithm
273
     * @return integer
274
     */
275
    protected function _getMhashDefinition($hashAlgorithm)
276
    {
277
        for ($i = 0; $i <= mhash_count(); $i++) {
278
            $types[mhash_get_hash_name($i)] = $i;
279
        }
280
        return $types[strtoupper($hashAlgorithm)];
281
    }
282
 
283
    /**
284
     * Digest method when using native functions which allows the selection
285
     * of raw binary output.
286
     *
287
     * @param string $hash
288
     * @param string $key
289
     * @param string $mode
290
     * @return string
291
     */
292
    protected function _digest($hash, $key, $mode)
293
    {
294
        if ($mode == self::BINARY) {
295
            return $hash($key, true);
296
        }
297
        return $hash($key);
298
    }
299
 
300
}