4 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
6 * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
8 * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
10 * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
11 * the hash. If no valid algorithm is provided, sha1 will be used.
13 * PHP versions 4 and 5
15 * {@internal The variable names are the same as those in
16 * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
18 * Here's a short example of how to use this library:
21 * include 'Crypt/Hash.php';
23 * $hash = new Crypt_Hash('sha1');
25 * $hash->setKey('abcdefg');
27 * echo base64_encode($hash->hash('abcdefg'));
31 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
32 * of this software and associated documentation files (the "Software"), to deal
33 * in the Software without restriction, including without limitation the rights
34 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35 * copies of the Software, and to permit persons to whom the Software is
36 * furnished to do so, subject to the following conditions:
38 * The above copyright notice and this permission notice shall be included in
39 * all copies or substantial portions of the Software.
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51 * @author Jim Wigginton <terrafrost@php.net>
52 * @copyright 2007 Jim Wigginton
53 * @license http://www.opensource.org/licenses/mit-license.html MIT License
54 * @link http://phpseclib.sourceforge.net
59 * @see Crypt_Hash::Crypt_Hash()
62 * Toggles the internal implementation
64 define('CRYPT_HASH_MODE_INTERNAL', 1);
66 * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
68 define('CRYPT_HASH_MODE_MHASH', 2);
70 * Toggles the hash() implementation, which works on PHP 5.1.2+.
72 define('CRYPT_HASH_MODE_HASH', 3);
76 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
79 * @author Jim Wigginton <terrafrost@php.net>
87 * @see Crypt_Hash::setHash()
94 * Byte-length of compression blocks / key (Internal HMAC)
96 * @see Crypt_Hash::setAlgorithm()
103 * Byte-length of hash output (Internal HMAC)
105 * @see Crypt_Hash::setHash()
114 * @see Crypt_Hash::setHash()
123 * @see Crypt_Hash::setKey()
130 * Outer XOR (Internal HMAC)
132 * @see Crypt_Hash::setKey()
139 * Inner XOR (Internal HMAC)
141 * @see Crypt_Hash::setKey()
148 * Default Constructor.
150 * @param optional String $hash
154 function Crypt_Hash($hash = 'sha1')
156 if ( !defined('CRYPT_HASH_MODE') ) {
158 case extension_loaded('hash'):
159 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
161 case extension_loaded('mhash'):
162 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
165 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
169 $this->setHash($hash);
173 * Sets the key for HMACs
175 * Keys can be of any length.
178 * @param optional String $key
180 function setKey($key = false)
186 * Gets the hash function.
188 * As set by the constructor or by the setHash() method.
195 return $this->hashParam;
199 * Sets the hash function.
202 * @param String $hash
204 function setHash($hash)
206 $this->hashParam = $hash = strtolower($hash);
212 $hash = substr($hash, 0, -3);
213 $this->l = 12; // 96 / 8 = 12
234 $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
235 CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
239 $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
242 $mode = CRYPT_HASH_MODE;
246 case CRYPT_HASH_MODE_MHASH:
249 $this->hash = MHASH_MD5;
252 $this->hash = MHASH_SHA256;
256 $this->hash = MHASH_SHA1;
259 case CRYPT_HASH_MODE_HASH:
272 $this->hash = 'sha1';
280 $this->hash = array($this, '_md2');
284 $this->hash = array($this, '_md5');
288 $this->hash = array($this, '_sha256');
293 $this->hash = array($this, '_sha512');
298 $this->hash = array($this, '_sha1');
301 $this->ipad = str_repeat(chr(0x36), $this->b);
302 $this->opad = str_repeat(chr(0x5C), $this->b);
309 * @param String $text
314 $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
316 if (!empty($this->key) || is_string($this->key)) {
318 case CRYPT_HASH_MODE_MHASH:
319 $output = mhash($this->hash, $text, $this->key);
321 case CRYPT_HASH_MODE_HASH:
322 $output = hash_hmac($this->hash, $text, $this->key, true);
324 case CRYPT_HASH_MODE_INTERNAL:
325 /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
326 resultant L byte string as the actual key to HMAC."
328 -- http://tools.ietf.org/html/rfc2104#section-2 */
329 $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
331 $key = str_pad($key, $this->b, chr(0)); // step 1
332 $temp = $this->ipad ^ $key; // step 2
333 $temp .= $text; // step 3
334 $temp = call_user_func($this->hash, $temp); // step 4
335 $output = $this->opad ^ $key; // step 5
336 $output.= $temp; // step 6
337 $output = call_user_func($this->hash, $output); // step 7
341 case CRYPT_HASH_MODE_MHASH:
342 $output = mhash($this->hash, $text);
344 case CRYPT_HASH_MODE_HASH:
345 $output = hash($this->hash, $text, true);
347 case CRYPT_HASH_MODE_INTERNAL:
348 $output = call_user_func($this->hash, $text);
352 return substr($output, 0, $this->l);
356 * Returns the hash length (in bytes)
374 return pack('H*', md5($m));
385 return pack('H*', sha1($m));
389 * Pure-PHP implementation of MD2
391 * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
399 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
400 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
401 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
402 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
403 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
404 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
405 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
406 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
407 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
408 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
409 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
410 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
411 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
412 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
413 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
414 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
415 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
416 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
419 // Step 1. Append Padding Bytes
420 $pad = 16 - (strlen($m) & 0xF);
421 $m.= str_repeat(chr($pad), $pad);
423 $length = strlen($m);
425 // Step 2. Append Checksum
426 $c = str_repeat(chr(0), 16);
428 for ($i = 0; $i < $length; $i+= 16) {
429 for ($j = 0; $j < 16; $j++) {
430 // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
431 //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
432 // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
433 $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
441 // Step 3. Initialize MD Buffer
442 $x = str_repeat(chr(0), 48);
444 // Step 4. Process Message in 16-Byte Blocks
445 for ($i = 0; $i < $length; $i+= 16) {
446 for ($j = 0; $j < 16; $j++) {
447 $x[$j + 16] = $m[$i + $j];
448 $x[$j + 32] = $x[$j + 16] ^ $x[$j];
451 for ($j = 0; $j < 18; $j++) {
452 for ($k = 0; $k < 48; $k++) {
453 $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
454 //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
456 $t = chr(ord($t) + $j);
461 return substr($x, 0, 16);
465 * Pure-PHP implementation of SHA256
467 * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
474 if (extension_loaded('suhosin')) {
475 return pack('H*', sha256($m));
478 // Initialize variables
480 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
482 // Initialize table of round constants
483 // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
485 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
486 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
487 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
488 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
489 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
490 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
491 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
492 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
496 $length = strlen($m);
497 // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
498 $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
499 $m[$length] = chr(0x80);
500 // we don't support hashing strings 512MB long
501 $m.= pack('N2', 0, $length << 3);
503 // Process the message in successive 512-bit chunks
504 $chunks = str_split($m, 64);
505 foreach ($chunks as $chunk) {
507 for ($i = 0; $i < 16; $i++) {
508 extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
512 // Extend the sixteen 32-bit words into sixty-four 32-bit words
513 for ($i = 16; $i < 64; $i++) {
514 $s0 = $this->_rightRotate($w[$i - 15], 7) ^
515 $this->_rightRotate($w[$i - 15], 18) ^
516 $this->_rightShift( $w[$i - 15], 3);
517 $s1 = $this->_rightRotate($w[$i - 2], 17) ^
518 $this->_rightRotate($w[$i - 2], 19) ^
519 $this->_rightShift( $w[$i - 2], 10);
520 $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
524 // Initialize hash value for this chunk
525 list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
528 for ($i = 0; $i < 64; $i++) {
529 $s0 = $this->_rightRotate($a, 2) ^
530 $this->_rightRotate($a, 13) ^
531 $this->_rightRotate($a, 22);
535 $t2 = $this->_add($s0, $maj);
537 $s1 = $this->_rightRotate($e, 6) ^
538 $this->_rightRotate($e, 11) ^
539 $this->_rightRotate($e, 25);
541 ($this->_not($e) & $g);
542 $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
547 $e = $this->_add($d, $t1);
551 $a = $this->_add($t1, $t2);
554 // Add this chunk's hash to result so far
556 $this->_add($hash[0], $a),
557 $this->_add($hash[1], $b),
558 $this->_add($hash[2], $c),
559 $this->_add($hash[3], $d),
560 $this->_add($hash[4], $e),
561 $this->_add($hash[5], $f),
562 $this->_add($hash[6], $g),
563 $this->_add($hash[7], $h)
567 // Produce the final hash value (big-endian)
568 return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
572 * Pure-PHP implementation of SHA384 and SHA512
579 if (!class_exists('Math_BigInteger')) {
580 include_once 'Math/BigInteger.php';
583 static $init384, $init512, $k;
586 // Initialize variables
587 $init384 = array( // initial values for SHA384
588 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
589 '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
591 $init512 = array( // initial values for SHA512
592 '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
593 '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
596 for ($i = 0; $i < 8; $i++) {
597 $init384[$i] = new Math_BigInteger($init384[$i], 16);
598 $init384[$i]->setPrecision(64);
599 $init512[$i] = new Math_BigInteger($init512[$i], 16);
600 $init512[$i]->setPrecision(64);
603 // Initialize table of round constants
604 // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
606 '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
607 '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
608 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
609 '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
610 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
611 '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
612 '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
613 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
614 '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
615 '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
616 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
617 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
618 '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
619 '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
620 '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
621 '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
622 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
623 '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
624 '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
625 '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
628 for ($i = 0; $i < 80; $i++) {
629 $k[$i] = new Math_BigInteger($k[$i], 16);
633 $hash = $this->l == 48 ? $init384 : $init512;
636 $length = strlen($m);
637 // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
638 $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
639 $m[$length] = chr(0x80);
640 // we don't support hashing strings 512MB long
641 $m.= pack('N4', 0, 0, 0, $length << 3);
643 // Process the message in successive 1024-bit chunks
644 $chunks = str_split($m, 128);
645 foreach ($chunks as $chunk) {
647 for ($i = 0; $i < 16; $i++) {
648 $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
649 $temp->setPrecision(64);
653 // Extend the sixteen 32-bit words into eighty 32-bit words
654 for ($i = 16; $i < 80; $i++) {
656 $w[$i - 15]->bitwise_rightRotate(1),
657 $w[$i - 15]->bitwise_rightRotate(8),
658 $w[$i - 15]->bitwise_rightShift(7)
660 $s0 = $temp[0]->bitwise_xor($temp[1]);
661 $s0 = $s0->bitwise_xor($temp[2]);
663 $w[$i - 2]->bitwise_rightRotate(19),
664 $w[$i - 2]->bitwise_rightRotate(61),
665 $w[$i - 2]->bitwise_rightShift(6)
667 $s1 = $temp[0]->bitwise_xor($temp[1]);
668 $s1 = $s1->bitwise_xor($temp[2]);
669 $w[$i] = $w[$i - 16]->copy();
670 $w[$i] = $w[$i]->add($s0);
671 $w[$i] = $w[$i]->add($w[$i - 7]);
672 $w[$i] = $w[$i]->add($s1);
675 // Initialize hash value for this chunk
676 $a = $hash[0]->copy();
677 $b = $hash[1]->copy();
678 $c = $hash[2]->copy();
679 $d = $hash[3]->copy();
680 $e = $hash[4]->copy();
681 $f = $hash[5]->copy();
682 $g = $hash[6]->copy();
683 $h = $hash[7]->copy();
686 for ($i = 0; $i < 80; $i++) {
688 $a->bitwise_rightRotate(28),
689 $a->bitwise_rightRotate(34),
690 $a->bitwise_rightRotate(39)
692 $s0 = $temp[0]->bitwise_xor($temp[1]);
693 $s0 = $s0->bitwise_xor($temp[2]);
699 $maj = $temp[0]->bitwise_xor($temp[1]);
700 $maj = $maj->bitwise_xor($temp[2]);
701 $t2 = $s0->add($maj);
704 $e->bitwise_rightRotate(14),
705 $e->bitwise_rightRotate(18),
706 $e->bitwise_rightRotate(41)
708 $s1 = $temp[0]->bitwise_xor($temp[1]);
709 $s1 = $s1->bitwise_xor($temp[2]);
712 $g->bitwise_and($e->bitwise_not())
714 $ch = $temp[0]->bitwise_xor($temp[1]);
717 $t1 = $t1->add($k[$i]);
718 $t1 = $t1->add($w[$i]);
730 // Add this chunk's hash to result so far
743 // Produce the final hash value (big-endian)
744 // (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
745 $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
746 $hash[4]->toBytes() . $hash[5]->toBytes();
747 if ($this->l != 48) {
748 $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
758 * @param Integer $int
759 * @param Integer $amt
763 function _rightRotate($int, $amt)
766 $mask = (1 << $invamt) - 1;
767 return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
774 * @param Integer $int
775 * @param Integer $amt
779 function _rightShift($int, $amt)
781 $mask = (1 << (32 - $amt)) - 1;
782 return ($int >> $amt) & $mask;
789 * @param Integer $int
795 return ~$int & 0xFFFFFFFF;
801 * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
802 * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
804 * @param Integer $...
817 $arguments = func_get_args();
818 foreach ($arguments as $argument) {
819 $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
822 return fmod($result, $mod);
828 * Inspired by array_shift
830 * @param String $string
831 * @param optional Integer $index
835 function _string_shift(&$string, $index = 1)
837 $substr = substr($string, 0, $index);
838 $string = substr($string, $index);