Version Description
- fix an E_NOTICE (thanks, runblip!)
- make it so keys that are copy / pasted in are saved with HTML5's localStorage (thanks, kkzk!)
- update phpseclib to latest Git
Download this release
Release Info
Developer | TerraFrost |
Plugin | SSH SFTP Updater Support |
Version | 0.4 |
Comparing to | |
See all releases |
Code changes from version 0.3 to 0.4
- phpseclib/Crypt/AES.php +55 -36
- phpseclib/Crypt/DES.php +12 -13
- phpseclib/Crypt/Hash.php +825 -825
- phpseclib/Crypt/RC4.php +531 -564
- phpseclib/Crypt/RSA.php +234 -108
- phpseclib/Crypt/Random.php +164 -64
- phpseclib/Crypt/Rijndael.php +1501 -1477
- phpseclib/Crypt/TripleDES.php +12 -10
- phpseclib/Math/BigInteger.php +117 -35
- phpseclib/Net/SFTP.php +159 -85
- phpseclib/Net/SSH2.php +319 -104
- readme.txt +8 -3
- sftp.php +10 -2
phpseclib/Crypt/AES.php
CHANGED
@@ -66,7 +66,9 @@
|
|
66 |
/**
|
67 |
* Include Crypt_Rijndael
|
68 |
*/
|
69 |
-
|
|
|
|
|
70 |
|
71 |
/**#@+
|
72 |
* @access public
|
@@ -178,10 +180,7 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
178 |
{
|
179 |
if ( !defined('CRYPT_AES_MODE') ) {
|
180 |
switch (true) {
|
181 |
-
case extension_loaded('mcrypt'):
|
182 |
-
// i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),
|
183 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
184 |
-
// a lot of point...
|
185 |
define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
|
186 |
break;
|
187 |
default:
|
@@ -215,8 +214,6 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
215 |
$this->mode = MCRYPT_MODE_CBC;
|
216 |
}
|
217 |
|
218 |
-
$this->debuffer = $this->enbuffer = '';
|
219 |
-
|
220 |
break;
|
221 |
default:
|
222 |
switch ($mode) {
|
@@ -312,18 +309,20 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
312 |
// re: http://phpseclib.sourceforge.net/cfb-demo.phps
|
313 |
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
|
314 |
// rewritten CFB implementation the above outputs the same thing twice.
|
315 |
-
if ($this->mode == 'ncfb') {
|
316 |
if ($changed) {
|
317 |
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
318 |
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
319 |
}
|
320 |
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
|
|
|
|
327 |
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
328 |
}
|
329 |
$plaintext = substr($plaintext, strlen($ciphertext));
|
@@ -332,15 +331,15 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
332 |
}
|
333 |
|
334 |
$last_pos = strlen($plaintext) & 0xFFFFFFF0;
|
335 |
-
|
|
|
|
|
|
|
336 |
|
337 |
if (strlen($plaintext) & 0xF) {
|
338 |
-
if (strlen($ciphertext)) {
|
339 |
-
$this->encryptIV = substr($ciphertext, -16);
|
340 |
-
}
|
341 |
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
|
342 |
-
$
|
343 |
-
$ciphertext.= $
|
344 |
}
|
345 |
|
346 |
return $ciphertext;
|
@@ -387,19 +386,21 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
387 |
return $plaintext;
|
388 |
}
|
389 |
*/
|
390 |
-
if ($this->mode == 'ncfb') {
|
391 |
if ($changed) {
|
392 |
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
393 |
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
394 |
}
|
395 |
|
396 |
-
|
397 |
-
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
|
398 |
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
|
|
|
|
|
|
403 |
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
404 |
}
|
405 |
$ciphertext = substr($ciphertext, strlen($plaintext));
|
@@ -408,15 +409,15 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
408 |
}
|
409 |
|
410 |
$last_pos = strlen($ciphertext) & 0xFFFFFFF0;
|
411 |
-
|
|
|
|
|
|
|
|
|
412 |
|
413 |
if (strlen($ciphertext) & 0xF) {
|
414 |
-
|
415 |
-
|
416 |
-
}
|
417 |
-
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
|
418 |
-
$this->debuffer = substr($ciphertext, $last_pos);
|
419 |
-
$plaintext.= $this->debuffer ^ $this->decryptIV;
|
420 |
}
|
421 |
|
422 |
return $plaintext;
|
@@ -527,7 +528,7 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
527 |
// shiftRows + subWord + mixColumns + addRoundKey
|
528 |
// we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
|
529 |
// only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
|
530 |
-
for ($round = 1; $round < $
|
531 |
$state = array(
|
532 |
$t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
|
533 |
$t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
|
@@ -587,7 +588,7 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
587 |
|
588 |
|
589 |
// invShiftRows + invSubBytes + invMixColumns + addRoundKey
|
590 |
-
for ($round = $
|
591 |
$state = array(
|
592 |
$dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
|
593 |
$dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
|
@@ -606,6 +607,24 @@ class Crypt_AES extends Crypt_Rijndael {
|
|
606 |
|
607 |
return pack('N*', $state[0], $state[1], $state[2], $state[3]);
|
608 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
609 |
}
|
610 |
|
611 |
// vim: ts=4:sw=4:et:
|
66 |
/**
|
67 |
* Include Crypt_Rijndael
|
68 |
*/
|
69 |
+
if (!class_exists('Crypt_Rijndael')) {
|
70 |
+
require_once 'Rijndael.php';
|
71 |
+
}
|
72 |
|
73 |
/**#@+
|
74 |
* @access public
|
180 |
{
|
181 |
if ( !defined('CRYPT_AES_MODE') ) {
|
182 |
switch (true) {
|
183 |
+
case extension_loaded('mcrypt') && in_array('rijndael-128', mcrypt_list_algorithms()):
|
|
|
|
|
|
|
184 |
define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
|
185 |
break;
|
186 |
default:
|
214 |
$this->mode = MCRYPT_MODE_CBC;
|
215 |
}
|
216 |
|
|
|
|
|
217 |
break;
|
218 |
default:
|
219 |
switch ($mode) {
|
309 |
// re: http://phpseclib.sourceforge.net/cfb-demo.phps
|
310 |
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
|
311 |
// rewritten CFB implementation the above outputs the same thing twice.
|
312 |
+
if ($this->mode == 'ncfb' && $this->continuousBuffer) {
|
313 |
if ($changed) {
|
314 |
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
315 |
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
316 |
}
|
317 |
|
318 |
+
$buffer = &$this->enbuffer['encrypted'];
|
319 |
+
|
320 |
+
if (strlen($buffer)) {
|
321 |
+
$ciphertext = $plaintext ^ substr($this->encryptIV, strlen($buffer));
|
322 |
+
$buffer.= $ciphertext;
|
323 |
+
if (strlen($buffer) == 16) {
|
324 |
+
$this->encryptIV = $buffer;
|
325 |
+
$buffer = '';
|
326 |
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
327 |
}
|
328 |
$plaintext = substr($plaintext, strlen($ciphertext));
|
331 |
}
|
332 |
|
333 |
$last_pos = strlen($plaintext) & 0xFFFFFFF0;
|
334 |
+
if ($last_pos) {
|
335 |
+
$ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos));
|
336 |
+
$this->encryptIV = substr($ciphertext, -16);
|
337 |
+
}
|
338 |
|
339 |
if (strlen($plaintext) & 0xF) {
|
|
|
|
|
|
|
340 |
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
|
341 |
+
$buffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
|
342 |
+
$ciphertext.= $buffer;
|
343 |
}
|
344 |
|
345 |
return $ciphertext;
|
386 |
return $plaintext;
|
387 |
}
|
388 |
*/
|
389 |
+
if ($this->mode == 'ncfb' && $this->continuousBuffer) {
|
390 |
if ($changed) {
|
391 |
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
|
392 |
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
|
393 |
}
|
394 |
|
395 |
+
$buffer = &$this->debuffer['ciphertext'];
|
|
|
396 |
|
397 |
+
if (strlen($buffer)) {
|
398 |
+
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer));
|
399 |
+
|
400 |
+
$buffer.= substr($ciphertext, 0, strlen($plaintext));
|
401 |
+
if (strlen($buffer) == 16) {
|
402 |
+
$this->decryptIV = $buffer;
|
403 |
+
$buffer = '';
|
404 |
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
405 |
}
|
406 |
$ciphertext = substr($ciphertext, strlen($plaintext));
|
409 |
}
|
410 |
|
411 |
$last_pos = strlen($ciphertext) & 0xFFFFFFF0;
|
412 |
+
if ($last_pos) {
|
413 |
+
$plaintext = mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos));
|
414 |
+
$this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
|
415 |
+
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
|
416 |
+
}
|
417 |
|
418 |
if (strlen($ciphertext) & 0xF) {
|
419 |
+
$buffer = substr($ciphertext, $last_pos);
|
420 |
+
$plaintext.= $buffer ^ $this->decryptIV;
|
|
|
|
|
|
|
|
|
421 |
}
|
422 |
|
423 |
return $plaintext;
|
528 |
// shiftRows + subWord + mixColumns + addRoundKey
|
529 |
// we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
|
530 |
// only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
|
531 |
+
for ($round = 1; $round < $Nr; $round++) {
|
532 |
$state = array(
|
533 |
$t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
|
534 |
$t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
|
588 |
|
589 |
|
590 |
// invShiftRows + invSubBytes + invMixColumns + addRoundKey
|
591 |
+
for ($round = $Nr - 1; $round > 0; $round--) {
|
592 |
$state = array(
|
593 |
$dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
|
594 |
$dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
|
607 |
|
608 |
return pack('N*', $state[0], $state[1], $state[2], $state[3]);
|
609 |
}
|
610 |
+
|
611 |
+
/**
|
612 |
+
* Treat consecutive packets as if they are a discontinuous buffer.
|
613 |
+
*
|
614 |
+
* The default behavior.
|
615 |
+
*
|
616 |
+
* @see Crypt_Rijndael::enableContinuousBuffer()
|
617 |
+
* @access public
|
618 |
+
*/
|
619 |
+
function disableContinuousBuffer()
|
620 |
+
{
|
621 |
+
parent::disableContinuousBuffer();
|
622 |
+
|
623 |
+
if (CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT) {
|
624 |
+
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
|
625 |
+
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
626 |
+
}
|
627 |
+
}
|
628 |
}
|
629 |
|
630 |
// vim: ts=4:sw=4:et:
|
phpseclib/Crypt/DES.php
CHANGED
@@ -291,14 +291,11 @@ class Crypt_DES {
|
|
291 |
* @return Crypt_DES
|
292 |
* @access public
|
293 |
*/
|
294 |
-
function Crypt_DES($mode =
|
295 |
{
|
296 |
if ( !defined('CRYPT_DES_MODE') ) {
|
297 |
switch (true) {
|
298 |
-
case extension_loaded('mcrypt'):
|
299 |
-
// i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
|
300 |
-
// but since that can be changed after the object has been created, there doesn't seem to be
|
301 |
-
// a lot of point...
|
302 |
define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
|
303 |
break;
|
304 |
default:
|
@@ -374,7 +371,7 @@ class Crypt_DES {
|
|
374 |
*
|
375 |
* Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
|
376 |
* {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
|
377 |
-
* $hash, $salt, $
|
378 |
*
|
379 |
* @param String $password
|
380 |
* @param optional String $method
|
@@ -392,7 +389,7 @@ class Crypt_DES {
|
|
392 |
}
|
393 |
// WPA and WPA use the SSID as the salt
|
394 |
if (!isset($salt)) {
|
395 |
-
$salt = 'phpseclib';
|
396 |
}
|
397 |
// RFC2898#section-4.2 uses 1,000 iterations by default
|
398 |
// WPA and WPA2 use 4,096.
|
@@ -600,7 +597,7 @@ class Crypt_DES {
|
|
600 |
}
|
601 |
break;
|
602 |
case CRYPT_DES_MODE_CFB:
|
603 |
-
if (
|
604 |
$ciphertext = $plaintext ^ $buffer['xor'];
|
605 |
$iv = $buffer['encrypted'] . $ciphertext;
|
606 |
$start = strlen($ciphertext);
|
@@ -726,7 +723,7 @@ class Crypt_DES {
|
|
726 |
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
727 |
}
|
728 |
|
729 |
-
return $this->
|
730 |
}
|
731 |
|
732 |
if (!is_array($this->keys)) {
|
@@ -777,15 +774,17 @@ class Crypt_DES {
|
|
777 |
}
|
778 |
break;
|
779 |
case CRYPT_DES_MODE_CFB:
|
780 |
-
if (
|
781 |
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
782 |
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
783 |
-
if (strlen($buffer['ciphertext'])
|
|
|
|
|
|
|
784 |
$xor = $this->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
|
785 |
$buffer['ciphertext'] = '';
|
786 |
}
|
787 |
$start = strlen($plaintext);
|
788 |
-
$block = $this->decryptIV;
|
789 |
} else {
|
790 |
$plaintext = '';
|
791 |
$xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
|
@@ -940,7 +939,7 @@ class Crypt_DES {
|
|
940 |
if (($length & 7) == 0) {
|
941 |
return $text;
|
942 |
} else {
|
943 |
-
user_error("The plaintext's length ($length) is not a multiple of the block size (8)"
|
944 |
$this->padding = true;
|
945 |
}
|
946 |
}
|
291 |
* @return Crypt_DES
|
292 |
* @access public
|
293 |
*/
|
294 |
+
function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
|
295 |
{
|
296 |
if ( !defined('CRYPT_DES_MODE') ) {
|
297 |
switch (true) {
|
298 |
+
case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()):
|
|
|
|
|
|
|
299 |
define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
|
300 |
break;
|
301 |
default:
|
371 |
*
|
372 |
* Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
|
373 |
* {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
|
374 |
+
* $hash, $salt, $count
|
375 |
*
|
376 |
* @param String $password
|
377 |
* @param optional String $method
|
389 |
}
|
390 |
// WPA and WPA use the SSID as the salt
|
391 |
if (!isset($salt)) {
|
392 |
+
$salt = 'phpseclib/salt';
|
393 |
}
|
394 |
// RFC2898#section-4.2 uses 1,000 iterations by default
|
395 |
// WPA and WPA2 use 4,096.
|
597 |
}
|
598 |
break;
|
599 |
case CRYPT_DES_MODE_CFB:
|
600 |
+
if (strlen($buffer['xor'])) {
|
601 |
$ciphertext = $plaintext ^ $buffer['xor'];
|
602 |
$iv = $buffer['encrypted'] . $ciphertext;
|
603 |
$start = strlen($ciphertext);
|
723 |
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
724 |
}
|
725 |
|
726 |
+
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
727 |
}
|
728 |
|
729 |
if (!is_array($this->keys)) {
|
774 |
}
|
775 |
break;
|
776 |
case CRYPT_DES_MODE_CFB:
|
777 |
+
if (strlen($buffer['ciphertext'])) {
|
778 |
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
|
779 |
$buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
|
780 |
+
if (strlen($buffer['ciphertext']) != 8) {
|
781 |
+
$block = $this->decryptIV;
|
782 |
+
} else {
|
783 |
+
$block = $buffer['ciphertext'];
|
784 |
$xor = $this->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
|
785 |
$buffer['ciphertext'] = '';
|
786 |
}
|
787 |
$start = strlen($plaintext);
|
|
|
788 |
} else {
|
789 |
$plaintext = '';
|
790 |
$xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
|
939 |
if (($length & 7) == 0) {
|
940 |
return $text;
|
941 |
} else {
|
942 |
+
user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
|
943 |
$this->padding = true;
|
944 |
}
|
945 |
}
|
phpseclib/Crypt/Hash.php
CHANGED
@@ -1,825 +1,825 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
6 |
-
*
|
7 |
-
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
|
8 |
-
*
|
9 |
-
* md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
|
10 |
-
*
|
11 |
-
* If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
|
12 |
-
* the hash. If no valid algorithm is provided, sha1 will be used.
|
13 |
-
*
|
14 |
-
* PHP versions 4 and 5
|
15 |
-
*
|
16 |
-
* {@internal The variable names are the same as those in
|
17 |
-
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
|
18 |
-
*
|
19 |
-
* Here's a short example of how to use this library:
|
20 |
-
* <code>
|
21 |
-
* <?php
|
22 |
-
* include('Crypt/Hash.php');
|
23 |
-
*
|
24 |
-
* $hash = new Crypt_Hash('sha1');
|
25 |
-
*
|
26 |
-
* $hash->setKey('abcdefg');
|
27 |
-
*
|
28 |
-
* echo base64_encode($hash->hash('abcdefg'));
|
29 |
-
* ?>
|
30 |
-
* </code>
|
31 |
-
*
|
32 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
33 |
-
* of this software and associated documentation files (the "Software"), to deal
|
34 |
-
* in the Software without restriction, including without limitation the rights
|
35 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
36 |
-
* copies of the Software, and to permit persons to whom the Software is
|
37 |
-
* furnished to do so, subject to the following conditions:
|
38 |
-
*
|
39 |
-
* The above copyright notice and this permission notice shall be included in
|
40 |
-
* all copies or substantial portions of the Software.
|
41 |
-
*
|
42 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
43 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
44 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
45 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
46 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
47 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
48 |
-
* THE SOFTWARE.
|
49 |
-
*
|
50 |
-
* @category Crypt
|
51 |
-
* @package Crypt_Hash
|
52 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
53 |
-
* @copyright MMVII Jim Wigginton
|
54 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
55 |
-
* @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
|
56 |
-
* @link http://phpseclib.sourceforge.net
|
57 |
-
*/
|
58 |
-
|
59 |
-
/**#@+
|
60 |
-
* @access private
|
61 |
-
* @see Crypt_Hash::Crypt_Hash()
|
62 |
-
*/
|
63 |
-
/**
|
64 |
-
* Toggles the internal implementation
|
65 |
-
*/
|
66 |
-
define('CRYPT_HASH_MODE_INTERNAL', 1);
|
67 |
-
/**
|
68 |
-
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
|
69 |
-
*/
|
70 |
-
define('CRYPT_HASH_MODE_MHASH', 2);
|
71 |
-
/**
|
72 |
-
* Toggles the hash() implementation, which works on PHP 5.1.2+.
|
73 |
-
*/
|
74 |
-
define('CRYPT_HASH_MODE_HASH', 3);
|
75 |
-
/**#@-*/
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
79 |
-
*
|
80 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
81 |
-
* @version 0.1.0
|
82 |
-
* @access public
|
83 |
-
* @package Crypt_Hash
|
84 |
-
*/
|
85 |
-
class Crypt_Hash {
|
86 |
-
/**
|
87 |
-
* Byte-length of compression blocks / key (Internal HMAC)
|
88 |
-
*
|
89 |
-
* @see Crypt_Hash::setAlgorithm()
|
90 |
-
* @var Integer
|
91 |
-
* @access private
|
92 |
-
*/
|
93 |
-
var $b;
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Byte-length of hash output (Internal HMAC)
|
97 |
-
*
|
98 |
-
* @see Crypt_Hash::setHash()
|
99 |
-
* @var Integer
|
100 |
-
* @access private
|
101 |
-
*/
|
102 |
-
var $l = false;
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Hash Algorithm
|
106 |
-
*
|
107 |
-
* @see Crypt_Hash::setHash()
|
108 |
-
* @var String
|
109 |
-
* @access private
|
110 |
-
*/
|
111 |
-
var $hash;
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Key
|
115 |
-
*
|
116 |
-
* @see Crypt_Hash::setKey()
|
117 |
-
* @var String
|
118 |
-
* @access private
|
119 |
-
*/
|
120 |
-
var $key =
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Outer XOR (Internal HMAC)
|
124 |
-
*
|
125 |
-
* @see Crypt_Hash::setKey()
|
126 |
-
* @var String
|
127 |
-
* @access private
|
128 |
-
*/
|
129 |
-
var $opad;
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Inner XOR (Internal HMAC)
|
133 |
-
*
|
134 |
-
* @see Crypt_Hash::setKey()
|
135 |
-
* @var String
|
136 |
-
* @access private
|
137 |
-
*/
|
138 |
-
var $ipad;
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Default Constructor.
|
142 |
-
*
|
143 |
-
* @param optional String $hash
|
144 |
-
* @return Crypt_Hash
|
145 |
-
* @access public
|
146 |
-
*/
|
147 |
-
function Crypt_Hash($hash = 'sha1')
|
148 |
-
{
|
149 |
-
if ( !defined('CRYPT_HASH_MODE') ) {
|
150 |
-
switch (true) {
|
151 |
-
case extension_loaded('hash'):
|
152 |
-
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
|
153 |
-
break;
|
154 |
-
case extension_loaded('mhash'):
|
155 |
-
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
|
156 |
-
break;
|
157 |
-
default:
|
158 |
-
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
|
159 |
-
}
|
160 |
-
}
|
161 |
-
|
162 |
-
$this->setHash($hash);
|
163 |
-
}
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Sets the key for HMACs
|
167 |
-
*
|
168 |
-
* Keys can be of any length.
|
169 |
-
*
|
170 |
-
* @access public
|
171 |
-
* @param String $key
|
172 |
-
*/
|
173 |
-
function setKey($key)
|
174 |
-
{
|
175 |
-
$this->key = $key;
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* Sets the hash function.
|
180 |
-
*
|
181 |
-
* @access public
|
182 |
-
* @param String $hash
|
183 |
-
*/
|
184 |
-
function setHash($hash)
|
185 |
-
{
|
186 |
-
$hash = strtolower($hash);
|
187 |
-
switch ($hash) {
|
188 |
-
case 'md5-96':
|
189 |
-
case 'sha1-96':
|
190 |
-
$this->l = 12; // 96 / 8 = 12
|
191 |
-
break;
|
192 |
-
case 'md2':
|
193 |
-
case 'md5':
|
194 |
-
$this->l = 16;
|
195 |
-
break;
|
196 |
-
case 'sha1':
|
197 |
-
$this->l = 20;
|
198 |
-
break;
|
199 |
-
case 'sha256':
|
200 |
-
$this->l = 32;
|
201 |
-
break;
|
202 |
-
case 'sha384':
|
203 |
-
$this->l = 48;
|
204 |
-
break;
|
205 |
-
case 'sha512':
|
206 |
-
$this->l = 64;
|
207 |
-
}
|
208 |
-
|
209 |
-
switch ($hash) {
|
210 |
-
case 'md2':
|
211 |
-
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
|
212 |
-
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
|
213 |
-
break;
|
214 |
-
case 'sha384':
|
215 |
-
case 'sha512':
|
216 |
-
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
217 |
-
break;
|
218 |
-
default:
|
219 |
-
$mode = CRYPT_HASH_MODE;
|
220 |
-
}
|
221 |
-
|
222 |
-
switch ( $mode ) {
|
223 |
-
case CRYPT_HASH_MODE_MHASH:
|
224 |
-
switch ($hash) {
|
225 |
-
case 'md5':
|
226 |
-
case 'md5-96':
|
227 |
-
$this->hash = MHASH_MD5;
|
228 |
-
break;
|
229 |
-
case 'sha256':
|
230 |
-
$this->hash = MHASH_SHA256;
|
231 |
-
break;
|
232 |
-
case 'sha1':
|
233 |
-
case 'sha1-96':
|
234 |
-
default:
|
235 |
-
$this->hash = MHASH_SHA1;
|
236 |
-
}
|
237 |
-
return;
|
238 |
-
case CRYPT_HASH_MODE_HASH:
|
239 |
-
switch ($hash) {
|
240 |
-
case 'md5':
|
241 |
-
case 'md5-96':
|
242 |
-
$this->hash = 'md5';
|
243 |
-
return;
|
244 |
-
case 'md2':
|
245 |
-
case 'sha256':
|
246 |
-
case 'sha384':
|
247 |
-
case 'sha512':
|
248 |
-
$this->hash = $hash;
|
249 |
-
return;
|
250 |
-
case 'sha1':
|
251 |
-
case 'sha1-96':
|
252 |
-
default:
|
253 |
-
$this->hash = 'sha1';
|
254 |
-
}
|
255 |
-
return;
|
256 |
-
}
|
257 |
-
|
258 |
-
switch ($hash) {
|
259 |
-
case 'md2':
|
260 |
-
$this->b = 16;
|
261 |
-
$this->hash = array($this, '_md2');
|
262 |
-
break;
|
263 |
-
case 'md5':
|
264 |
-
case 'md5-96':
|
265 |
-
$this->b = 64;
|
266 |
-
$this->hash = array($this, '_md5');
|
267 |
-
break;
|
268 |
-
case 'sha256':
|
269 |
-
$this->b = 64;
|
270 |
-
$this->hash = array($this, '_sha256');
|
271 |
-
break;
|
272 |
-
case 'sha384':
|
273 |
-
case 'sha512':
|
274 |
-
$this->b = 128;
|
275 |
-
$this->hash = array($this, '_sha512');
|
276 |
-
break;
|
277 |
-
case 'sha1':
|
278 |
-
case 'sha1-96':
|
279 |
-
default:
|
280 |
-
$this->b = 64;
|
281 |
-
$this->hash = array($this, '_sha1');
|
282 |
-
}
|
283 |
-
|
284 |
-
$this->ipad = str_repeat(chr(0x36), $this->b);
|
285 |
-
$this->opad = str_repeat(chr(0x5C), $this->b);
|
286 |
-
}
|
287 |
-
|
288 |
-
/**
|
289 |
-
* Compute the HMAC.
|
290 |
-
*
|
291 |
-
* @access public
|
292 |
-
* @param String $text
|
293 |
-
* @return String
|
294 |
-
*/
|
295 |
-
function hash($text)
|
296 |
-
{
|
297 |
-
$mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
298 |
-
|
299 |
-
if (!empty($this->key)) {
|
300 |
-
switch ( $mode ) {
|
301 |
-
case CRYPT_HASH_MODE_MHASH:
|
302 |
-
$output = mhash($this->hash, $text, $this->key);
|
303 |
-
break;
|
304 |
-
case CRYPT_HASH_MODE_HASH:
|
305 |
-
$output = hash_hmac($this->hash, $text, $this->key, true);
|
306 |
-
break;
|
307 |
-
case CRYPT_HASH_MODE_INTERNAL:
|
308 |
-
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
309 |
-
resultant L byte string as the actual key to HMAC."
|
310 |
-
|
311 |
-
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
312 |
-
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
313 |
-
|
314 |
-
$key = str_pad($key, $this->b, chr(0)); // step 1
|
315 |
-
$temp = $this->ipad ^ $key; // step 2
|
316 |
-
$temp .= $text; // step 3
|
317 |
-
$temp = call_user_func($this->hash, $temp); // step 4
|
318 |
-
$output = $this->opad ^ $key; // step 5
|
319 |
-
$output.= $temp; // step 6
|
320 |
-
$output = call_user_func($this->hash, $output); // step 7
|
321 |
-
}
|
322 |
-
} else {
|
323 |
-
switch ( $mode ) {
|
324 |
-
case CRYPT_HASH_MODE_MHASH:
|
325 |
-
$output = mhash($this->hash, $text);
|
326 |
-
break;
|
327 |
-
case CRYPT_HASH_MODE_HASH:
|
328 |
-
$output = hash($this->hash, $text, true);
|
329 |
-
break;
|
330 |
-
case CRYPT_HASH_MODE_INTERNAL:
|
331 |
-
$output = call_user_func($this->hash, $text);
|
332 |
-
}
|
333 |
-
}
|
334 |
-
|
335 |
-
return substr($output, 0, $this->l);
|
336 |
-
}
|
337 |
-
|
338 |
-
/**
|
339 |
-
* Returns the hash length (in bytes)
|
340 |
-
*
|
341 |
-
* @access public
|
342 |
-
* @return Integer
|
343 |
-
*/
|
344 |
-
function getLength()
|
345 |
-
{
|
346 |
-
return $this->l;
|
347 |
-
}
|
348 |
-
|
349 |
-
/**
|
350 |
-
* Wrapper for MD5
|
351 |
-
*
|
352 |
-
* @access private
|
353 |
-
* @param String $text
|
354 |
-
*/
|
355 |
-
function _md5($m)
|
356 |
-
{
|
357 |
-
return pack('H*', md5($m));
|
358 |
-
}
|
359 |
-
|
360 |
-
/**
|
361 |
-
* Wrapper for SHA1
|
362 |
-
*
|
363 |
-
* @access private
|
364 |
-
* @param String $text
|
365 |
-
*/
|
366 |
-
function _sha1($m)
|
367 |
-
{
|
368 |
-
return pack('H*', sha1($m));
|
369 |
-
}
|
370 |
-
|
371 |
-
/**
|
372 |
-
* Pure-PHP implementation of MD2
|
373 |
-
*
|
374 |
-
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
|
375 |
-
*
|
376 |
-
* @access private
|
377 |
-
* @param String $text
|
378 |
-
*/
|
379 |
-
function _md2($m)
|
380 |
-
{
|
381 |
-
static $s = array(
|
382 |
-
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
383 |
-
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
384 |
-
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
385 |
-
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
386 |
-
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
387 |
-
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
388 |
-
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
389 |
-
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
390 |
-
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
391 |
-
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
392 |
-
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
393 |
-
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
394 |
-
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
395 |
-
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
396 |
-
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
397 |
-
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
398 |
-
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
399 |
-
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
400 |
-
);
|
401 |
-
|
402 |
-
// Step 1. Append Padding Bytes
|
403 |
-
$pad = 16 - (strlen($m) & 0xF);
|
404 |
-
$m.= str_repeat(chr($pad), $pad);
|
405 |
-
|
406 |
-
$length = strlen($m);
|
407 |
-
|
408 |
-
// Step 2. Append Checksum
|
409 |
-
$c = str_repeat(chr(0), 16);
|
410 |
-
$l = chr(0);
|
411 |
-
for ($i = 0; $i < $length; $i+= 16) {
|
412 |
-
for ($j = 0; $j < 16; $j++) {
|
413 |
-
// RFC1319 incorrectly states that C[j] should be set to S[c xor L]
|
414 |
-
//$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
|
415 |
-
// 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]
|
416 |
-
$c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
|
417 |
-
$l = $c[$j];
|
418 |
-
}
|
419 |
-
}
|
420 |
-
$m.= $c;
|
421 |
-
|
422 |
-
$length+= 16;
|
423 |
-
|
424 |
-
// Step 3. Initialize MD Buffer
|
425 |
-
$x = str_repeat(chr(0), 48);
|
426 |
-
|
427 |
-
// Step 4. Process Message in 16-Byte Blocks
|
428 |
-
for ($i = 0; $i < $length; $i+= 16) {
|
429 |
-
for ($j = 0; $j < 16; $j++) {
|
430 |
-
$x[$j + 16] = $m[$i + $j];
|
431 |
-
$x[$j + 32] = $x[$j + 16] ^ $x[$j];
|
432 |
-
}
|
433 |
-
$t = chr(0);
|
434 |
-
for ($j = 0; $j < 18; $j++) {
|
435 |
-
for ($k = 0; $k < 48; $k++) {
|
436 |
-
$x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
|
437 |
-
//$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
|
438 |
-
}
|
439 |
-
$t = chr(ord($t) + $j);
|
440 |
-
}
|
441 |
-
}
|
442 |
-
|
443 |
-
// Step 5. Output
|
444 |
-
return substr($x, 0, 16);
|
445 |
-
}
|
446 |
-
|
447 |
-
/**
|
448 |
-
* Pure-PHP implementation of SHA256
|
449 |
-
*
|
450 |
-
* 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}.
|
451 |
-
*
|
452 |
-
* @access private
|
453 |
-
* @param String $text
|
454 |
-
*/
|
455 |
-
function _sha256($m)
|
456 |
-
{
|
457 |
-
if (extension_loaded('suhosin')) {
|
458 |
-
return pack('H*', sha256($m));
|
459 |
-
}
|
460 |
-
|
461 |
-
// Initialize variables
|
462 |
-
$hash = array(
|
463 |
-
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
464 |
-
);
|
465 |
-
// Initialize table of round constants
|
466 |
-
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
|
467 |
-
static $k = array(
|
468 |
-
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
469 |
-
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
470 |
-
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
471 |
-
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
472 |
-
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
473 |
-
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
474 |
-
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
475 |
-
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
476 |
-
);
|
477 |
-
|
478 |
-
// Pre-processing
|
479 |
-
$length = strlen($m);
|
480 |
-
// to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
|
481 |
-
$m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
|
482 |
-
$m[$length] = chr(0x80);
|
483 |
-
// we don't support hashing strings 512MB long
|
484 |
-
$m.= pack('N2', 0, $length << 3);
|
485 |
-
|
486 |
-
// Process the message in successive 512-bit chunks
|
487 |
-
$chunks = str_split($m, 64);
|
488 |
-
foreach ($chunks as $chunk) {
|
489 |
-
$w = array();
|
490 |
-
for ($i = 0; $i < 16; $i++) {
|
491 |
-
extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
|
492 |
-
$w[] = $temp;
|
493 |
-
}
|
494 |
-
|
495 |
-
// Extend the sixteen 32-bit words into sixty-four 32-bit words
|
496 |
-
for ($i = 16; $i < 64; $i++) {
|
497 |
-
$s0 = $this->_rightRotate($w[$i - 15], 7) ^
|
498 |
-
$this->_rightRotate($w[$i - 15], 18) ^
|
499 |
-
$this->_rightShift( $w[$i - 15], 3);
|
500 |
-
$s1 = $this->_rightRotate($w[$i - 2], 17) ^
|
501 |
-
$this->_rightRotate($w[$i - 2], 19) ^
|
502 |
-
$this->_rightShift( $w[$i - 2], 10);
|
503 |
-
$w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
|
504 |
-
|
505 |
-
}
|
506 |
-
|
507 |
-
// Initialize hash value for this chunk
|
508 |
-
list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
|
509 |
-
|
510 |
-
// Main loop
|
511 |
-
for ($i = 0; $i < 64; $i++) {
|
512 |
-
$s0 = $this->_rightRotate($a, 2) ^
|
513 |
-
$this->_rightRotate($a, 13) ^
|
514 |
-
$this->_rightRotate($a, 22);
|
515 |
-
$maj = ($a & $b) ^
|
516 |
-
($a & $c) ^
|
517 |
-
($b & $c);
|
518 |
-
$t2 = $this->_add($s0, $maj);
|
519 |
-
|
520 |
-
$s1 = $this->_rightRotate($e, 6) ^
|
521 |
-
$this->_rightRotate($e, 11) ^
|
522 |
-
$this->_rightRotate($e, 25);
|
523 |
-
$ch = ($e & $f) ^
|
524 |
-
($this->_not($e) & $g);
|
525 |
-
$t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
|
526 |
-
|
527 |
-
$h = $g;
|
528 |
-
$g = $f;
|
529 |
-
$f = $e;
|
530 |
-
$e = $this->_add($d, $t1);
|
531 |
-
$d = $c;
|
532 |
-
$c = $b;
|
533 |
-
$b = $a;
|
534 |
-
$a = $this->_add($t1, $t2);
|
535 |
-
}
|
536 |
-
|
537 |
-
// Add this chunk's hash to result so far
|
538 |
-
$hash = array(
|
539 |
-
$this->_add($hash[0], $a),
|
540 |
-
$this->_add($hash[1], $b),
|
541 |
-
$this->_add($hash[2], $c),
|
542 |
-
$this->_add($hash[3], $d),
|
543 |
-
$this->_add($hash[4], $e),
|
544 |
-
$this->_add($hash[5], $f),
|
545 |
-
$this->_add($hash[6], $g),
|
546 |
-
$this->_add($hash[7], $h)
|
547 |
-
);
|
548 |
-
}
|
549 |
-
|
550 |
-
// Produce the final hash value (big-endian)
|
551 |
-
return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
|
552 |
-
}
|
553 |
-
|
554 |
-
/**
|
555 |
-
* Pure-PHP implementation of SHA384 and SHA512
|
556 |
-
*
|
557 |
-
* @access private
|
558 |
-
* @param String $text
|
559 |
-
*/
|
560 |
-
function _sha512($m)
|
561 |
-
{
|
562 |
-
if (!class_exists('Math_BigInteger')) {
|
563 |
-
require_once('Math/BigInteger.php');
|
564 |
-
}
|
565 |
-
|
566 |
-
static $init384, $init512, $k;
|
567 |
-
|
568 |
-
if (!isset($k)) {
|
569 |
-
// Initialize variables
|
570 |
-
$init384 = array( // initial values for SHA384
|
571 |
-
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
|
572 |
-
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
|
573 |
-
);
|
574 |
-
$init512 = array( // initial values for SHA512
|
575 |
-
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
|
576 |
-
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
|
577 |
-
);
|
578 |
-
|
579 |
-
for ($i = 0; $i < 8; $i++) {
|
580 |
-
$init384[$i] = new Math_BigInteger($init384[$i], 16);
|
581 |
-
$init384[$i]->setPrecision(64);
|
582 |
-
$init512[$i] = new Math_BigInteger($init512[$i], 16);
|
583 |
-
$init512[$i]->setPrecision(64);
|
584 |
-
}
|
585 |
-
|
586 |
-
// Initialize table of round constants
|
587 |
-
// (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
|
588 |
-
$k = array(
|
589 |
-
'428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
|
590 |
-
'3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
|
591 |
-
'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
|
592 |
-
'72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
|
593 |
-
'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
|
594 |
-
'2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
|
595 |
-
'983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
|
596 |
-
'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
|
597 |
-
'27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
|
598 |
-
'650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
|
599 |
-
'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
|
600 |
-
'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
|
601 |
-
'19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
|
602 |
-
'391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
|
603 |
-
'748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
|
604 |
-
'90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
|
605 |
-
'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
|
606 |
-
'06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
|
607 |
-
'28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
|
608 |
-
'4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
|
609 |
-
);
|
610 |
-
|
611 |
-
for ($i = 0; $i < 80; $i++) {
|
612 |
-
$k[$i] = new Math_BigInteger($k[$i], 16);
|
613 |
-
}
|
614 |
-
}
|
615 |
-
|
616 |
-
$hash = $this->l == 48 ? $init384 : $init512;
|
617 |
-
|
618 |
-
// Pre-processing
|
619 |
-
$length = strlen($m);
|
620 |
-
// to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
|
621 |
-
$m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
|
622 |
-
$m[$length] = chr(0x80);
|
623 |
-
// we don't support hashing strings 512MB long
|
624 |
-
$m.= pack('N4', 0, 0, 0, $length << 3);
|
625 |
-
|
626 |
-
// Process the message in successive 1024-bit chunks
|
627 |
-
$chunks = str_split($m, 128);
|
628 |
-
foreach ($chunks as $chunk) {
|
629 |
-
$w = array();
|
630 |
-
for ($i = 0; $i < 16; $i++) {
|
631 |
-
$temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
|
632 |
-
$temp->setPrecision(64);
|
633 |
-
$w[] = $temp;
|
634 |
-
}
|
635 |
-
|
636 |
-
// Extend the sixteen 32-bit words into eighty 32-bit words
|
637 |
-
for ($i = 16; $i < 80; $i++) {
|
638 |
-
$temp = array(
|
639 |
-
$w[$i - 15]->bitwise_rightRotate(1),
|
640 |
-
$w[$i - 15]->bitwise_rightRotate(8),
|
641 |
-
$w[$i - 15]->bitwise_rightShift(7)
|
642 |
-
);
|
643 |
-
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
644 |
-
$s0 = $s0->bitwise_xor($temp[2]);
|
645 |
-
$temp = array(
|
646 |
-
$w[$i - 2]->bitwise_rightRotate(19),
|
647 |
-
$w[$i - 2]->bitwise_rightRotate(61),
|
648 |
-
$w[$i - 2]->bitwise_rightShift(6)
|
649 |
-
);
|
650 |
-
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
651 |
-
$s1 = $s1->bitwise_xor($temp[2]);
|
652 |
-
$w[$i] = $w[$i - 16]->copy();
|
653 |
-
$w[$i] = $w[$i]->add($s0);
|
654 |
-
$w[$i] = $w[$i]->add($w[$i - 7]);
|
655 |
-
$w[$i] = $w[$i]->add($s1);
|
656 |
-
}
|
657 |
-
|
658 |
-
// Initialize hash value for this chunk
|
659 |
-
$a = $hash[0]->copy();
|
660 |
-
$b = $hash[1]->copy();
|
661 |
-
$c = $hash[2]->copy();
|
662 |
-
$d = $hash[3]->copy();
|
663 |
-
$e = $hash[4]->copy();
|
664 |
-
$f = $hash[5]->copy();
|
665 |
-
$g = $hash[6]->copy();
|
666 |
-
$h = $hash[7]->copy();
|
667 |
-
|
668 |
-
// Main loop
|
669 |
-
for ($i = 0; $i < 80; $i++) {
|
670 |
-
$temp = array(
|
671 |
-
$a->bitwise_rightRotate(28),
|
672 |
-
$a->bitwise_rightRotate(34),
|
673 |
-
$a->bitwise_rightRotate(39)
|
674 |
-
);
|
675 |
-
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
676 |
-
$s0 = $s0->bitwise_xor($temp[2]);
|
677 |
-
$temp = array(
|
678 |
-
$a->bitwise_and($b),
|
679 |
-
$a->bitwise_and($c),
|
680 |
-
$b->bitwise_and($c)
|
681 |
-
);
|
682 |
-
$maj = $temp[0]->bitwise_xor($temp[1]);
|
683 |
-
$maj = $maj->bitwise_xor($temp[2]);
|
684 |
-
$t2 = $s0->add($maj);
|
685 |
-
|
686 |
-
$temp = array(
|
687 |
-
$e->bitwise_rightRotate(14),
|
688 |
-
$e->bitwise_rightRotate(18),
|
689 |
-
$e->bitwise_rightRotate(41)
|
690 |
-
);
|
691 |
-
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
692 |
-
$s1 = $s1->bitwise_xor($temp[2]);
|
693 |
-
$temp = array(
|
694 |
-
$e->bitwise_and($f),
|
695 |
-
$g->bitwise_and($e->bitwise_not())
|
696 |
-
);
|
697 |
-
$ch = $temp[0]->bitwise_xor($temp[1]);
|
698 |
-
$t1 = $h->add($s1);
|
699 |
-
$t1 = $t1->add($ch);
|
700 |
-
$t1 = $t1->add($k[$i]);
|
701 |
-
$t1 = $t1->add($w[$i]);
|
702 |
-
|
703 |
-
$h = $g->copy();
|
704 |
-
$g = $f->copy();
|
705 |
-
$f = $e->copy();
|
706 |
-
$e = $d->add($t1);
|
707 |
-
$d = $c->copy();
|
708 |
-
$c = $b->copy();
|
709 |
-
$b = $a->copy();
|
710 |
-
$a = $t1->add($t2);
|
711 |
-
}
|
712 |
-
|
713 |
-
// Add this chunk's hash to result so far
|
714 |
-
$hash = array(
|
715 |
-
$hash[0]->add($a),
|
716 |
-
$hash[1]->add($b),
|
717 |
-
$hash[2]->add($c),
|
718 |
-
$hash[3]->add($d),
|
719 |
-
$hash[4]->add($e),
|
720 |
-
$hash[5]->add($f),
|
721 |
-
$hash[6]->add($g),
|
722 |
-
$hash[7]->add($h)
|
723 |
-
);
|
724 |
-
}
|
725 |
-
|
726 |
-
// Produce the final hash value (big-endian)
|
727 |
-
// (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
|
728 |
-
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
|
729 |
-
$hash[4]->toBytes() . $hash[5]->toBytes();
|
730 |
-
if ($this->l != 48) {
|
731 |
-
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
|
732 |
-
}
|
733 |
-
|
734 |
-
return $temp;
|
735 |
-
}
|
736 |
-
|
737 |
-
/**
|
738 |
-
* Right Rotate
|
739 |
-
*
|
740 |
-
* @access private
|
741 |
-
* @param Integer $int
|
742 |
-
* @param Integer $amt
|
743 |
-
* @see _sha256()
|
744 |
-
* @return Integer
|
745 |
-
*/
|
746 |
-
function _rightRotate($int, $amt)
|
747 |
-
{
|
748 |
-
$invamt = 32 - $amt;
|
749 |
-
$mask = (1 << $invamt) - 1;
|
750 |
-
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
|
751 |
-
}
|
752 |
-
|
753 |
-
/**
|
754 |
-
* Right Shift
|
755 |
-
*
|
756 |
-
* @access private
|
757 |
-
* @param Integer $int
|
758 |
-
* @param Integer $amt
|
759 |
-
* @see _sha256()
|
760 |
-
* @return Integer
|
761 |
-
*/
|
762 |
-
function _rightShift($int, $amt)
|
763 |
-
{
|
764 |
-
$mask = (1 << (32 - $amt)) - 1;
|
765 |
-
return ($int >> $amt) & $mask;
|
766 |
-
}
|
767 |
-
|
768 |
-
/**
|
769 |
-
* Not
|
770 |
-
*
|
771 |
-
* @access private
|
772 |
-
* @param Integer $int
|
773 |
-
* @see _sha256()
|
774 |
-
* @return Integer
|
775 |
-
*/
|
776 |
-
function _not($int)
|
777 |
-
{
|
778 |
-
return ~$int & 0xFFFFFFFF;
|
779 |
-
}
|
780 |
-
|
781 |
-
/**
|
782 |
-
* Add
|
783 |
-
*
|
784 |
-
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
|
785 |
-
* possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
|
786 |
-
*
|
787 |
-
* @param String $string
|
788 |
-
* @param optional Integer $index
|
789 |
-
* @return String
|
790 |
-
* @see _sha256()
|
791 |
-
* @access private
|
792 |
-
*/
|
793 |
-
function _add()
|
794 |
-
{
|
795 |
-
static $mod;
|
796 |
-
if (!isset($mod)) {
|
797 |
-
$mod = pow(2, 32);
|
798 |
-
}
|
799 |
-
|
800 |
-
$result = 0;
|
801 |
-
$arguments = func_get_args();
|
802 |
-
foreach ($arguments as $argument) {
|
803 |
-
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
804 |
-
}
|
805 |
-
|
806 |
-
return fmod($result, $mod);
|
807 |
-
}
|
808 |
-
|
809 |
-
/**
|
810 |
-
* String Shift
|
811 |
-
*
|
812 |
-
* Inspired by array_shift
|
813 |
-
*
|
814 |
-
* @param String $string
|
815 |
-
* @param optional Integer $index
|
816 |
-
* @return String
|
817 |
-
* @access private
|
818 |
-
*/
|
819 |
-
function _string_shift(&$string, $index = 1)
|
820 |
-
{
|
821 |
-
$substr = substr($string, 0, $index);
|
822 |
-
$string = substr($string, $index);
|
823 |
-
return $substr;
|
824 |
-
}
|
825 |
-
}
|
1 |
+
<?php
|
2 |
+
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
6 |
+
*
|
7 |
+
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
|
8 |
+
*
|
9 |
+
* md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
|
10 |
+
*
|
11 |
+
* If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
|
12 |
+
* the hash. If no valid algorithm is provided, sha1 will be used.
|
13 |
+
*
|
14 |
+
* PHP versions 4 and 5
|
15 |
+
*
|
16 |
+
* {@internal The variable names are the same as those in
|
17 |
+
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
|
18 |
+
*
|
19 |
+
* Here's a short example of how to use this library:
|
20 |
+
* <code>
|
21 |
+
* <?php
|
22 |
+
* include('Crypt/Hash.php');
|
23 |
+
*
|
24 |
+
* $hash = new Crypt_Hash('sha1');
|
25 |
+
*
|
26 |
+
* $hash->setKey('abcdefg');
|
27 |
+
*
|
28 |
+
* echo base64_encode($hash->hash('abcdefg'));
|
29 |
+
* ?>
|
30 |
+
* </code>
|
31 |
+
*
|
32 |
+
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
33 |
+
* of this software and associated documentation files (the "Software"), to deal
|
34 |
+
* in the Software without restriction, including without limitation the rights
|
35 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
36 |
+
* copies of the Software, and to permit persons to whom the Software is
|
37 |
+
* furnished to do so, subject to the following conditions:
|
38 |
+
*
|
39 |
+
* The above copyright notice and this permission notice shall be included in
|
40 |
+
* all copies or substantial portions of the Software.
|
41 |
+
*
|
42 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
43 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
44 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
45 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
46 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
47 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
48 |
+
* THE SOFTWARE.
|
49 |
+
*
|
50 |
+
* @category Crypt
|
51 |
+
* @package Crypt_Hash
|
52 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
53 |
+
* @copyright MMVII Jim Wigginton
|
54 |
+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
55 |
+
* @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
|
56 |
+
* @link http://phpseclib.sourceforge.net
|
57 |
+
*/
|
58 |
+
|
59 |
+
/**#@+
|
60 |
+
* @access private
|
61 |
+
* @see Crypt_Hash::Crypt_Hash()
|
62 |
+
*/
|
63 |
+
/**
|
64 |
+
* Toggles the internal implementation
|
65 |
+
*/
|
66 |
+
define('CRYPT_HASH_MODE_INTERNAL', 1);
|
67 |
+
/**
|
68 |
+
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
|
69 |
+
*/
|
70 |
+
define('CRYPT_HASH_MODE_MHASH', 2);
|
71 |
+
/**
|
72 |
+
* Toggles the hash() implementation, which works on PHP 5.1.2+.
|
73 |
+
*/
|
74 |
+
define('CRYPT_HASH_MODE_HASH', 3);
|
75 |
+
/**#@-*/
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
79 |
+
*
|
80 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
81 |
+
* @version 0.1.0
|
82 |
+
* @access public
|
83 |
+
* @package Crypt_Hash
|
84 |
+
*/
|
85 |
+
class Crypt_Hash {
|
86 |
+
/**
|
87 |
+
* Byte-length of compression blocks / key (Internal HMAC)
|
88 |
+
*
|
89 |
+
* @see Crypt_Hash::setAlgorithm()
|
90 |
+
* @var Integer
|
91 |
+
* @access private
|
92 |
+
*/
|
93 |
+
var $b;
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Byte-length of hash output (Internal HMAC)
|
97 |
+
*
|
98 |
+
* @see Crypt_Hash::setHash()
|
99 |
+
* @var Integer
|
100 |
+
* @access private
|
101 |
+
*/
|
102 |
+
var $l = false;
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Hash Algorithm
|
106 |
+
*
|
107 |
+
* @see Crypt_Hash::setHash()
|
108 |
+
* @var String
|
109 |
+
* @access private
|
110 |
+
*/
|
111 |
+
var $hash;
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Key
|
115 |
+
*
|
116 |
+
* @see Crypt_Hash::setKey()
|
117 |
+
* @var String
|
118 |
+
* @access private
|
119 |
+
*/
|
120 |
+
var $key = false;
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Outer XOR (Internal HMAC)
|
124 |
+
*
|
125 |
+
* @see Crypt_Hash::setKey()
|
126 |
+
* @var String
|
127 |
+
* @access private
|
128 |
+
*/
|
129 |
+
var $opad;
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Inner XOR (Internal HMAC)
|
133 |
+
*
|
134 |
+
* @see Crypt_Hash::setKey()
|
135 |
+
* @var String
|
136 |
+
* @access private
|
137 |
+
*/
|
138 |
+
var $ipad;
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Default Constructor.
|
142 |
+
*
|
143 |
+
* @param optional String $hash
|
144 |
+
* @return Crypt_Hash
|
145 |
+
* @access public
|
146 |
+
*/
|
147 |
+
function Crypt_Hash($hash = 'sha1')
|
148 |
+
{
|
149 |
+
if ( !defined('CRYPT_HASH_MODE') ) {
|
150 |
+
switch (true) {
|
151 |
+
case extension_loaded('hash'):
|
152 |
+
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
|
153 |
+
break;
|
154 |
+
case extension_loaded('mhash'):
|
155 |
+
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
|
156 |
+
break;
|
157 |
+
default:
|
158 |
+
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
$this->setHash($hash);
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Sets the key for HMACs
|
167 |
+
*
|
168 |
+
* Keys can be of any length.
|
169 |
+
*
|
170 |
+
* @access public
|
171 |
+
* @param String $key
|
172 |
+
*/
|
173 |
+
function setKey($key = false)
|
174 |
+
{
|
175 |
+
$this->key = $key;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Sets the hash function.
|
180 |
+
*
|
181 |
+
* @access public
|
182 |
+
* @param String $hash
|
183 |
+
*/
|
184 |
+
function setHash($hash)
|
185 |
+
{
|
186 |
+
$hash = strtolower($hash);
|
187 |
+
switch ($hash) {
|
188 |
+
case 'md5-96':
|
189 |
+
case 'sha1-96':
|
190 |
+
$this->l = 12; // 96 / 8 = 12
|
191 |
+
break;
|
192 |
+
case 'md2':
|
193 |
+
case 'md5':
|
194 |
+
$this->l = 16;
|
195 |
+
break;
|
196 |
+
case 'sha1':
|
197 |
+
$this->l = 20;
|
198 |
+
break;
|
199 |
+
case 'sha256':
|
200 |
+
$this->l = 32;
|
201 |
+
break;
|
202 |
+
case 'sha384':
|
203 |
+
$this->l = 48;
|
204 |
+
break;
|
205 |
+
case 'sha512':
|
206 |
+
$this->l = 64;
|
207 |
+
}
|
208 |
+
|
209 |
+
switch ($hash) {
|
210 |
+
case 'md2':
|
211 |
+
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
|
212 |
+
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
|
213 |
+
break;
|
214 |
+
case 'sha384':
|
215 |
+
case 'sha512':
|
216 |
+
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
217 |
+
break;
|
218 |
+
default:
|
219 |
+
$mode = CRYPT_HASH_MODE;
|
220 |
+
}
|
221 |
+
|
222 |
+
switch ( $mode ) {
|
223 |
+
case CRYPT_HASH_MODE_MHASH:
|
224 |
+
switch ($hash) {
|
225 |
+
case 'md5':
|
226 |
+
case 'md5-96':
|
227 |
+
$this->hash = MHASH_MD5;
|
228 |
+
break;
|
229 |
+
case 'sha256':
|
230 |
+
$this->hash = MHASH_SHA256;
|
231 |
+
break;
|
232 |
+
case 'sha1':
|
233 |
+
case 'sha1-96':
|
234 |
+
default:
|
235 |
+
$this->hash = MHASH_SHA1;
|
236 |
+
}
|
237 |
+
return;
|
238 |
+
case CRYPT_HASH_MODE_HASH:
|
239 |
+
switch ($hash) {
|
240 |
+
case 'md5':
|
241 |
+
case 'md5-96':
|
242 |
+
$this->hash = 'md5';
|
243 |
+
return;
|
244 |
+
case 'md2':
|
245 |
+
case 'sha256':
|
246 |
+
case 'sha384':
|
247 |
+
case 'sha512':
|
248 |
+
$this->hash = $hash;
|
249 |
+
return;
|
250 |
+
case 'sha1':
|
251 |
+
case 'sha1-96':
|
252 |
+
default:
|
253 |
+
$this->hash = 'sha1';
|
254 |
+
}
|
255 |
+
return;
|
256 |
+
}
|
257 |
+
|
258 |
+
switch ($hash) {
|
259 |
+
case 'md2':
|
260 |
+
$this->b = 16;
|
261 |
+
$this->hash = array($this, '_md2');
|
262 |
+
break;
|
263 |
+
case 'md5':
|
264 |
+
case 'md5-96':
|
265 |
+
$this->b = 64;
|
266 |
+
$this->hash = array($this, '_md5');
|
267 |
+
break;
|
268 |
+
case 'sha256':
|
269 |
+
$this->b = 64;
|
270 |
+
$this->hash = array($this, '_sha256');
|
271 |
+
break;
|
272 |
+
case 'sha384':
|
273 |
+
case 'sha512':
|
274 |
+
$this->b = 128;
|
275 |
+
$this->hash = array($this, '_sha512');
|
276 |
+
break;
|
277 |
+
case 'sha1':
|
278 |
+
case 'sha1-96':
|
279 |
+
default:
|
280 |
+
$this->b = 64;
|
281 |
+
$this->hash = array($this, '_sha1');
|
282 |
+
}
|
283 |
+
|
284 |
+
$this->ipad = str_repeat(chr(0x36), $this->b);
|
285 |
+
$this->opad = str_repeat(chr(0x5C), $this->b);
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Compute the HMAC.
|
290 |
+
*
|
291 |
+
* @access public
|
292 |
+
* @param String $text
|
293 |
+
* @return String
|
294 |
+
*/
|
295 |
+
function hash($text)
|
296 |
+
{
|
297 |
+
$mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
298 |
+
|
299 |
+
if (!empty($this->key) || is_string($this->key)) {
|
300 |
+
switch ( $mode ) {
|
301 |
+
case CRYPT_HASH_MODE_MHASH:
|
302 |
+
$output = mhash($this->hash, $text, $this->key);
|
303 |
+
break;
|
304 |
+
case CRYPT_HASH_MODE_HASH:
|
305 |
+
$output = hash_hmac($this->hash, $text, $this->key, true);
|
306 |
+
break;
|
307 |
+
case CRYPT_HASH_MODE_INTERNAL:
|
308 |
+
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
309 |
+
resultant L byte string as the actual key to HMAC."
|
310 |
+
|
311 |
+
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
312 |
+
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
313 |
+
|
314 |
+
$key = str_pad($key, $this->b, chr(0)); // step 1
|
315 |
+
$temp = $this->ipad ^ $key; // step 2
|
316 |
+
$temp .= $text; // step 3
|
317 |
+
$temp = call_user_func($this->hash, $temp); // step 4
|
318 |
+
$output = $this->opad ^ $key; // step 5
|
319 |
+
$output.= $temp; // step 6
|
320 |
+
$output = call_user_func($this->hash, $output); // step 7
|
321 |
+
}
|
322 |
+
} else {
|
323 |
+
switch ( $mode ) {
|
324 |
+
case CRYPT_HASH_MODE_MHASH:
|
325 |
+
$output = mhash($this->hash, $text);
|
326 |
+
break;
|
327 |
+
case CRYPT_HASH_MODE_HASH:
|
328 |
+
$output = hash($this->hash, $text, true);
|
329 |
+
break;
|
330 |
+
case CRYPT_HASH_MODE_INTERNAL:
|
331 |
+
$output = call_user_func($this->hash, $text);
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
return substr($output, 0, $this->l);
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Returns the hash length (in bytes)
|
340 |
+
*
|
341 |
+
* @access public
|
342 |
+
* @return Integer
|
343 |
+
*/
|
344 |
+
function getLength()
|
345 |
+
{
|
346 |
+
return $this->l;
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Wrapper for MD5
|
351 |
+
*
|
352 |
+
* @access private
|
353 |
+
* @param String $text
|
354 |
+
*/
|
355 |
+
function _md5($m)
|
356 |
+
{
|
357 |
+
return pack('H*', md5($m));
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* Wrapper for SHA1
|
362 |
+
*
|
363 |
+
* @access private
|
364 |
+
* @param String $text
|
365 |
+
*/
|
366 |
+
function _sha1($m)
|
367 |
+
{
|
368 |
+
return pack('H*', sha1($m));
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Pure-PHP implementation of MD2
|
373 |
+
*
|
374 |
+
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
|
375 |
+
*
|
376 |
+
* @access private
|
377 |
+
* @param String $text
|
378 |
+
*/
|
379 |
+
function _md2($m)
|
380 |
+
{
|
381 |
+
static $s = array(
|
382 |
+
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
383 |
+
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
384 |
+
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
385 |
+
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
386 |
+
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
387 |
+
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
388 |
+
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
389 |
+
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
390 |
+
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
391 |
+
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
392 |
+
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
393 |
+
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
394 |
+
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
395 |
+
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
396 |
+
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
397 |
+
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
398 |
+
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
399 |
+
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
400 |
+
);
|
401 |
+
|
402 |
+
// Step 1. Append Padding Bytes
|
403 |
+
$pad = 16 - (strlen($m) & 0xF);
|
404 |
+
$m.= str_repeat(chr($pad), $pad);
|
405 |
+
|
406 |
+
$length = strlen($m);
|
407 |
+
|
408 |
+
// Step 2. Append Checksum
|
409 |
+
$c = str_repeat(chr(0), 16);
|
410 |
+
$l = chr(0);
|
411 |
+
for ($i = 0; $i < $length; $i+= 16) {
|
412 |
+
for ($j = 0; $j < 16; $j++) {
|
413 |
+
// RFC1319 incorrectly states that C[j] should be set to S[c xor L]
|
414 |
+
//$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
|
415 |
+
// 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]
|
416 |
+
$c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
|
417 |
+
$l = $c[$j];
|
418 |
+
}
|
419 |
+
}
|
420 |
+
$m.= $c;
|
421 |
+
|
422 |
+
$length+= 16;
|
423 |
+
|
424 |
+
// Step 3. Initialize MD Buffer
|
425 |
+
$x = str_repeat(chr(0), 48);
|
426 |
+
|
427 |
+
// Step 4. Process Message in 16-Byte Blocks
|
428 |
+
for ($i = 0; $i < $length; $i+= 16) {
|
429 |
+
for ($j = 0; $j < 16; $j++) {
|
430 |
+
$x[$j + 16] = $m[$i + $j];
|
431 |
+
$x[$j + 32] = $x[$j + 16] ^ $x[$j];
|
432 |
+
}
|
433 |
+
$t = chr(0);
|
434 |
+
for ($j = 0; $j < 18; $j++) {
|
435 |
+
for ($k = 0; $k < 48; $k++) {
|
436 |
+
$x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
|
437 |
+
//$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
|
438 |
+
}
|
439 |
+
$t = chr(ord($t) + $j);
|
440 |
+
}
|
441 |
+
}
|
442 |
+
|
443 |
+
// Step 5. Output
|
444 |
+
return substr($x, 0, 16);
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
* Pure-PHP implementation of SHA256
|
449 |
+
*
|
450 |
+
* 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}.
|
451 |
+
*
|
452 |
+
* @access private
|
453 |
+
* @param String $text
|
454 |
+
*/
|
455 |
+
function _sha256($m)
|
456 |
+
{
|
457 |
+
if (extension_loaded('suhosin')) {
|
458 |
+
return pack('H*', sha256($m));
|
459 |
+
}
|
460 |
+
|
461 |
+
// Initialize variables
|
462 |
+
$hash = array(
|
463 |
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
464 |
+
);
|
465 |
+
// Initialize table of round constants
|
466 |
+
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
|
467 |
+
static $k = array(
|
468 |
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
469 |
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
470 |
+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
471 |
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
472 |
+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
473 |
+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
474 |
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
475 |
+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
476 |
+
);
|
477 |
+
|
478 |
+
// Pre-processing
|
479 |
+
$length = strlen($m);
|
480 |
+
// to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
|
481 |
+
$m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
|
482 |
+
$m[$length] = chr(0x80);
|
483 |
+
// we don't support hashing strings 512MB long
|
484 |
+
$m.= pack('N2', 0, $length << 3);
|
485 |
+
|
486 |
+
// Process the message in successive 512-bit chunks
|
487 |
+
$chunks = str_split($m, 64);
|
488 |
+
foreach ($chunks as $chunk) {
|
489 |
+
$w = array();
|
490 |
+
for ($i = 0; $i < 16; $i++) {
|
491 |
+
extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
|
492 |
+
$w[] = $temp;
|
493 |
+
}
|
494 |
+
|
495 |
+
// Extend the sixteen 32-bit words into sixty-four 32-bit words
|
496 |
+
for ($i = 16; $i < 64; $i++) {
|
497 |
+
$s0 = $this->_rightRotate($w[$i - 15], 7) ^
|
498 |
+
$this->_rightRotate($w[$i - 15], 18) ^
|
499 |
+
$this->_rightShift( $w[$i - 15], 3);
|
500 |
+
$s1 = $this->_rightRotate($w[$i - 2], 17) ^
|
501 |
+
$this->_rightRotate($w[$i - 2], 19) ^
|
502 |
+
$this->_rightShift( $w[$i - 2], 10);
|
503 |
+
$w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
|
504 |
+
|
505 |
+
}
|
506 |
+
|
507 |
+
// Initialize hash value for this chunk
|
508 |
+
list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
|
509 |
+
|
510 |
+
// Main loop
|
511 |
+
for ($i = 0; $i < 64; $i++) {
|
512 |
+
$s0 = $this->_rightRotate($a, 2) ^
|
513 |
+
$this->_rightRotate($a, 13) ^
|
514 |
+
$this->_rightRotate($a, 22);
|
515 |
+
$maj = ($a & $b) ^
|
516 |
+
($a & $c) ^
|
517 |
+
($b & $c);
|
518 |
+
$t2 = $this->_add($s0, $maj);
|
519 |
+
|
520 |
+
$s1 = $this->_rightRotate($e, 6) ^
|
521 |
+
$this->_rightRotate($e, 11) ^
|
522 |
+
$this->_rightRotate($e, 25);
|
523 |
+
$ch = ($e & $f) ^
|
524 |
+
($this->_not($e) & $g);
|
525 |
+
$t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
|
526 |
+
|
527 |
+
$h = $g;
|
528 |
+
$g = $f;
|
529 |
+
$f = $e;
|
530 |
+
$e = $this->_add($d, $t1);
|
531 |
+
$d = $c;
|
532 |
+
$c = $b;
|
533 |
+
$b = $a;
|
534 |
+
$a = $this->_add($t1, $t2);
|
535 |
+
}
|
536 |
+
|
537 |
+
// Add this chunk's hash to result so far
|
538 |
+
$hash = array(
|
539 |
+
$this->_add($hash[0], $a),
|
540 |
+
$this->_add($hash[1], $b),
|
541 |
+
$this->_add($hash[2], $c),
|
542 |
+
$this->_add($hash[3], $d),
|
543 |
+
$this->_add($hash[4], $e),
|
544 |
+
$this->_add($hash[5], $f),
|
545 |
+
$this->_add($hash[6], $g),
|
546 |
+
$this->_add($hash[7], $h)
|
547 |
+
);
|
548 |
+
}
|
549 |
+
|
550 |
+
// Produce the final hash value (big-endian)
|
551 |
+
return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
|
552 |
+
}
|
553 |
+
|
554 |
+
/**
|
555 |
+
* Pure-PHP implementation of SHA384 and SHA512
|
556 |
+
*
|
557 |
+
* @access private
|
558 |
+
* @param String $text
|
559 |
+
*/
|
560 |
+
function _sha512($m)
|
561 |
+
{
|
562 |
+
if (!class_exists('Math_BigInteger')) {
|
563 |
+
require_once('Math/BigInteger.php');
|
564 |
+
}
|
565 |
+
|
566 |
+
static $init384, $init512, $k;
|
567 |
+
|
568 |
+
if (!isset($k)) {
|
569 |
+
// Initialize variables
|
570 |
+
$init384 = array( // initial values for SHA384
|
571 |
+
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
|
572 |
+
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
|
573 |
+
);
|
574 |
+
$init512 = array( // initial values for SHA512
|
575 |
+
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
|
576 |
+
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
|
577 |
+
);
|
578 |
+
|
579 |
+
for ($i = 0; $i < 8; $i++) {
|
580 |
+
$init384[$i] = new Math_BigInteger($init384[$i], 16);
|
581 |
+
$init384[$i]->setPrecision(64);
|
582 |
+
$init512[$i] = new Math_BigInteger($init512[$i], 16);
|
583 |
+
$init512[$i]->setPrecision(64);
|
584 |
+
}
|
585 |
+
|
586 |
+
// Initialize table of round constants
|
587 |
+
// (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
|
588 |
+
$k = array(
|
589 |
+
'428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
|
590 |
+
'3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
|
591 |
+
'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
|
592 |
+
'72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
|
593 |
+
'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
|
594 |
+
'2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
|
595 |
+
'983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
|
596 |
+
'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
|
597 |
+
'27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
|
598 |
+
'650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
|
599 |
+
'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
|
600 |
+
'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
|
601 |
+
'19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
|
602 |
+
'391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
|
603 |
+
'748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
|
604 |
+
'90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
|
605 |
+
'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
|
606 |
+
'06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
|
607 |
+
'28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
|
608 |
+
'4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
|
609 |
+
);
|
610 |
+
|
611 |
+
for ($i = 0; $i < 80; $i++) {
|
612 |
+
$k[$i] = new Math_BigInteger($k[$i], 16);
|
613 |
+
}
|
614 |
+
}
|
615 |
+
|
616 |
+
$hash = $this->l == 48 ? $init384 : $init512;
|
617 |
+
|
618 |
+
// Pre-processing
|
619 |
+
$length = strlen($m);
|
620 |
+
// to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
|
621 |
+
$m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
|
622 |
+
$m[$length] = chr(0x80);
|
623 |
+
// we don't support hashing strings 512MB long
|
624 |
+
$m.= pack('N4', 0, 0, 0, $length << 3);
|
625 |
+
|
626 |
+
// Process the message in successive 1024-bit chunks
|
627 |
+
$chunks = str_split($m, 128);
|
628 |
+
foreach ($chunks as $chunk) {
|
629 |
+
$w = array();
|
630 |
+
for ($i = 0; $i < 16; $i++) {
|
631 |
+
$temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
|
632 |
+
$temp->setPrecision(64);
|
633 |
+
$w[] = $temp;
|
634 |
+
}
|
635 |
+
|
636 |
+
// Extend the sixteen 32-bit words into eighty 32-bit words
|
637 |
+
for ($i = 16; $i < 80; $i++) {
|
638 |
+
$temp = array(
|
639 |
+
$w[$i - 15]->bitwise_rightRotate(1),
|
640 |
+
$w[$i - 15]->bitwise_rightRotate(8),
|
641 |
+
$w[$i - 15]->bitwise_rightShift(7)
|
642 |
+
);
|
643 |
+
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
644 |
+
$s0 = $s0->bitwise_xor($temp[2]);
|
645 |
+
$temp = array(
|
646 |
+
$w[$i - 2]->bitwise_rightRotate(19),
|
647 |
+
$w[$i - 2]->bitwise_rightRotate(61),
|
648 |
+
$w[$i - 2]->bitwise_rightShift(6)
|
649 |
+
);
|
650 |
+
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
651 |
+
$s1 = $s1->bitwise_xor($temp[2]);
|
652 |
+
$w[$i] = $w[$i - 16]->copy();
|
653 |
+
$w[$i] = $w[$i]->add($s0);
|
654 |
+
$w[$i] = $w[$i]->add($w[$i - 7]);
|
655 |
+
$w[$i] = $w[$i]->add($s1);
|
656 |
+
}
|
657 |
+
|
658 |
+
// Initialize hash value for this chunk
|
659 |
+
$a = $hash[0]->copy();
|
660 |
+
$b = $hash[1]->copy();
|
661 |
+
$c = $hash[2]->copy();
|
662 |
+
$d = $hash[3]->copy();
|
663 |
+
$e = $hash[4]->copy();
|
664 |
+
$f = $hash[5]->copy();
|
665 |
+
$g = $hash[6]->copy();
|
666 |
+
$h = $hash[7]->copy();
|
667 |
+
|
668 |
+
// Main loop
|
669 |
+
for ($i = 0; $i < 80; $i++) {
|
670 |
+
$temp = array(
|
671 |
+
$a->bitwise_rightRotate(28),
|
672 |
+
$a->bitwise_rightRotate(34),
|
673 |
+
$a->bitwise_rightRotate(39)
|
674 |
+
);
|
675 |
+
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
676 |
+
$s0 = $s0->bitwise_xor($temp[2]);
|
677 |
+
$temp = array(
|
678 |
+
$a->bitwise_and($b),
|
679 |
+
$a->bitwise_and($c),
|
680 |
+
$b->bitwise_and($c)
|
681 |
+
);
|
682 |
+
$maj = $temp[0]->bitwise_xor($temp[1]);
|
683 |
+
$maj = $maj->bitwise_xor($temp[2]);
|
684 |
+
$t2 = $s0->add($maj);
|
685 |
+
|
686 |
+
$temp = array(
|
687 |
+
$e->bitwise_rightRotate(14),
|
688 |
+
$e->bitwise_rightRotate(18),
|
689 |
+
$e->bitwise_rightRotate(41)
|
690 |
+
);
|
691 |
+
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
692 |
+
$s1 = $s1->bitwise_xor($temp[2]);
|
693 |
+
$temp = array(
|
694 |
+
$e->bitwise_and($f),
|
695 |
+
$g->bitwise_and($e->bitwise_not())
|
696 |
+
);
|
697 |
+
$ch = $temp[0]->bitwise_xor($temp[1]);
|
698 |
+
$t1 = $h->add($s1);
|
699 |
+
$t1 = $t1->add($ch);
|
700 |
+
$t1 = $t1->add($k[$i]);
|
701 |
+
$t1 = $t1->add($w[$i]);
|
702 |
+
|
703 |
+
$h = $g->copy();
|
704 |
+
$g = $f->copy();
|
705 |
+
$f = $e->copy();
|
706 |
+
$e = $d->add($t1);
|
707 |
+
$d = $c->copy();
|
708 |
+
$c = $b->copy();
|
709 |
+
$b = $a->copy();
|
710 |
+
$a = $t1->add($t2);
|
711 |
+
}
|
712 |
+
|
713 |
+
// Add this chunk's hash to result so far
|
714 |
+
$hash = array(
|
715 |
+
$hash[0]->add($a),
|
716 |
+
$hash[1]->add($b),
|
717 |
+
$hash[2]->add($c),
|
718 |
+
$hash[3]->add($d),
|
719 |
+
$hash[4]->add($e),
|
720 |
+
$hash[5]->add($f),
|
721 |
+
$hash[6]->add($g),
|
722 |
+
$hash[7]->add($h)
|
723 |
+
);
|
724 |
+
}
|
725 |
+
|
726 |
+
// Produce the final hash value (big-endian)
|
727 |
+
// (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
|
728 |
+
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
|
729 |
+
$hash[4]->toBytes() . $hash[5]->toBytes();
|
730 |
+
if ($this->l != 48) {
|
731 |
+
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
|
732 |
+
}
|
733 |
+
|
734 |
+
return $temp;
|
735 |
+
}
|
736 |
+
|
737 |
+
/**
|
738 |
+
* Right Rotate
|
739 |
+
*
|
740 |
+
* @access private
|
741 |
+
* @param Integer $int
|
742 |
+
* @param Integer $amt
|
743 |
+
* @see _sha256()
|
744 |
+
* @return Integer
|
745 |
+
*/
|
746 |
+
function _rightRotate($int, $amt)
|
747 |
+
{
|
748 |
+
$invamt = 32 - $amt;
|
749 |
+
$mask = (1 << $invamt) - 1;
|
750 |
+
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
|
751 |
+
}
|
752 |
+
|
753 |
+
/**
|
754 |
+
* Right Shift
|
755 |
+
*
|
756 |
+
* @access private
|
757 |
+
* @param Integer $int
|
758 |
+
* @param Integer $amt
|
759 |
+
* @see _sha256()
|
760 |
+
* @return Integer
|
761 |
+
*/
|
762 |
+
function _rightShift($int, $amt)
|
763 |
+
{
|
764 |
+
$mask = (1 << (32 - $amt)) - 1;
|
765 |
+
return ($int >> $amt) & $mask;
|
766 |
+
}
|
767 |
+
|
768 |
+
/**
|
769 |
+
* Not
|
770 |
+
*
|
771 |
+
* @access private
|
772 |
+
* @param Integer $int
|
773 |
+
* @see _sha256()
|
774 |
+
* @return Integer
|
775 |
+
*/
|
776 |
+
function _not($int)
|
777 |
+
{
|
778 |
+
return ~$int & 0xFFFFFFFF;
|
779 |
+
}
|
780 |
+
|
781 |
+
/**
|
782 |
+
* Add
|
783 |
+
*
|
784 |
+
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
|
785 |
+
* possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
|
786 |
+
*
|
787 |
+
* @param String $string
|
788 |
+
* @param optional Integer $index
|
789 |
+
* @return String
|
790 |
+
* @see _sha256()
|
791 |
+
* @access private
|
792 |
+
*/
|
793 |
+
function _add()
|
794 |
+
{
|
795 |
+
static $mod;
|
796 |
+
if (!isset($mod)) {
|
797 |
+
$mod = pow(2, 32);
|
798 |
+
}
|
799 |
+
|
800 |
+
$result = 0;
|
801 |
+
$arguments = func_get_args();
|
802 |
+
foreach ($arguments as $argument) {
|
803 |
+
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
804 |
+
}
|
805 |
+
|
806 |
+
return fmod($result, $mod);
|
807 |
+
}
|
808 |
+
|
809 |
+
/**
|
810 |
+
* String Shift
|
811 |
+
*
|
812 |
+
* Inspired by array_shift
|
813 |
+
*
|
814 |
+
* @param String $string
|
815 |
+
* @param optional Integer $index
|
816 |
+
* @return String
|
817 |
+
* @access private
|
818 |
+
*/
|
819 |
+
function _string_shift(&$string, $index = 1)
|
820 |
+
{
|
821 |
+
$substr = substr($string, 0, $index);
|
822 |
+
$string = substr($string, $index);
|
823 |
+
return $substr;
|
824 |
+
}
|
825 |
+
}
|
phpseclib/Crypt/RC4.php
CHANGED
@@ -1,564 +1,531 @@
|
|
1 |
-
<?php
|
2 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Pure-PHP implementation of RC4.
|
6 |
-
*
|
7 |
-
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
-
*
|
9 |
-
* PHP versions 4 and 5
|
10 |
-
*
|
11 |
-
* Useful resources are as follows:
|
12 |
-
*
|
13 |
-
* - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
|
14 |
-
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
|
15 |
-
*
|
16 |
-
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
|
17 |
-
* ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
|
18 |
-
*
|
19 |
-
* Here's a short example of how to use this library:
|
20 |
-
* <code>
|
21 |
-
* <?php
|
22 |
-
* include('Crypt/RC4.php');
|
23 |
-
*
|
24 |
-
* $rc4 = new Crypt_RC4();
|
25 |
-
*
|
26 |
-
* $rc4->setKey('abcdefgh');
|
27 |
-
*
|
28 |
-
* $size = 10 * 1024;
|
29 |
-
* $plaintext = '';
|
30 |
-
* for ($i = 0; $i < $size; $i++) {
|
31 |
-
* $plaintext.= 'a';
|
32 |
-
* }
|
33 |
-
*
|
34 |
-
* echo $rc4->decrypt($rc4->encrypt($plaintext));
|
35 |
-
* ?>
|
36 |
-
* </code>
|
37 |
-
*
|
38 |
-
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
39 |
-
* of this software and associated documentation files (the "Software"), to deal
|
40 |
-
* in the Software without restriction, including without limitation the rights
|
41 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
42 |
-
* copies of the Software, and to permit persons to whom the Software is
|
43 |
-
* furnished to do so, subject to the following conditions:
|
44 |
-
*
|
45 |
-
* The above copyright notice and this permission notice shall be included in
|
46 |
-
* all copies or substantial portions of the Software.
|
47 |
-
*
|
48 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
49 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
50 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
51 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
52 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
53 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
54 |
-
* THE SOFTWARE.
|
55 |
-
*
|
56 |
-
* @category Crypt
|
57 |
-
* @package Crypt_RC4
|
58 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
59 |
-
* @copyright MMVII Jim Wigginton
|
60 |
-
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
61 |
-
* @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
|
62 |
-
* @link http://phpseclib.sourceforge.net
|
63 |
-
*/
|
64 |
-
|
65 |
-
/**#@+
|
66 |
-
* @access private
|
67 |
-
* @see Crypt_RC4::Crypt_RC4()
|
68 |
-
*/
|
69 |
-
/**
|
70 |
-
* Toggles the internal implementation
|
71 |
-
*/
|
72 |
-
define('CRYPT_RC4_MODE_INTERNAL', 1);
|
73 |
-
/**
|
74 |
-
* Toggles the mcrypt implementation
|
75 |
-
*/
|
76 |
-
define('CRYPT_RC4_MODE_MCRYPT', 2);
|
77 |
-
/**#@-*/
|
78 |
-
|
79 |
-
/**#@+
|
80 |
-
* @access private
|
81 |
-
* @see Crypt_RC4::_crypt()
|
82 |
-
*/
|
83 |
-
define('CRYPT_RC4_ENCRYPT', 0);
|
84 |
-
define('CRYPT_RC4_DECRYPT', 1);
|
85 |
-
/**#@-*/
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Pure-PHP implementation of RC4.
|
89 |
-
*
|
90 |
-
* @author Jim Wigginton <terrafrost@php.net>
|
91 |
-
* @version 0.1.0
|
92 |
-
* @access public
|
93 |
-
* @package Crypt_RC4
|
94 |
-
*/
|
95 |
-
class Crypt_RC4 {
|
96 |
-
/**
|
97 |
-
* The Key
|
98 |
-
*
|
99 |
-
* @see Crypt_RC4::setKey()
|
100 |
-
* @var String
|
101 |
-
* @access private
|
102 |
-
*/
|
103 |
-
var $key = "\0";
|
104 |
-
|
105 |
-
/**
|
106 |
-
* The Key Stream for encryption
|
107 |
-
*
|
108 |
-
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
109 |
-
*
|
110 |
-
* @see Crypt_RC4::setKey()
|
111 |
-
* @var Array
|
112 |
-
* @access private
|
113 |
-
*/
|
114 |
-
var $encryptStream = false;
|
115 |
-
|
116 |
-
/**
|
117 |
-
* The Key Stream for decryption
|
118 |
-
*
|
119 |
-
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
120 |
-
*
|
121 |
-
* @see Crypt_RC4::setKey()
|
122 |
-
* @var Array
|
123 |
-
* @access private
|
124 |
-
*/
|
125 |
-
var $decryptStream = false;
|
126 |
-
|
127 |
-
/**
|
128 |
-
* The $i and $j indexes for encryption
|
129 |
-
*
|
130 |
-
* @see Crypt_RC4::_crypt()
|
131 |
-
* @var Integer
|
132 |
-
* @access private
|
133 |
-
*/
|
134 |
-
var $encryptIndex = 0;
|
135 |
-
|
136 |
-
/**
|
137 |
-
* The $i and $j indexes for decryption
|
138 |
-
*
|
139 |
-
* @see Crypt_RC4::_crypt()
|
140 |
-
* @var Integer
|
141 |
-
* @access private
|
142 |
-
*/
|
143 |
-
var $decryptIndex = 0;
|
144 |
-
|
145 |
-
/**
|
146 |
-
*
|
147 |
-
*
|
148 |
-
*
|
149 |
-
*
|
150 |
-
* @
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
*
|
158 |
-
*
|
159 |
-
* @see Crypt_RC4::
|
160 |
-
* @var
|
161 |
-
* @access private
|
162 |
-
*/
|
163 |
-
var $
|
164 |
-
|
165 |
-
/**
|
166 |
-
*
|
167 |
-
*
|
168 |
-
*
|
169 |
-
*
|
170 |
-
* @
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
$
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
$
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
if (!isset($
|
263 |
-
$
|
264 |
-
}
|
265 |
-
|
266 |
-
if (!
|
267 |
-
|
268 |
-
}
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
$count
|
273 |
-
|
274 |
-
|
275 |
-
$
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
*
|
305 |
-
*
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
*
|
313 |
-
*
|
314 |
-
*
|
315 |
-
*
|
316 |
-
*
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
*
|
328 |
-
*
|
329 |
-
*
|
330 |
-
*
|
331 |
-
* @
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
*
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
$
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
}
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
*
|
441 |
-
*
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
*
|
450 |
-
*
|
451 |
-
*
|
452 |
-
*
|
453 |
-
*
|
454 |
-
*
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
*
|
468 |
-
*
|
469 |
-
*
|
470 |
-
*
|
471 |
-
*
|
472 |
-
*
|
473 |
-
* @
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
*
|
483 |
-
*
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
*
|
506 |
-
*
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
533 |
-
$this->_closeMCrypt();
|
534 |
-
}
|
535 |
-
}
|
536 |
-
|
537 |
-
/**
|
538 |
-
* Properly close the MCrypt objects.
|
539 |
-
*
|
540 |
-
* @access prviate
|
541 |
-
*/
|
542 |
-
function _closeMCrypt()
|
543 |
-
{
|
544 |
-
if ( $this->encryptStream !== false ) {
|
545 |
-
if ( $this->continuousBuffer ) {
|
546 |
-
mcrypt_generic_deinit($this->encryptStream);
|
547 |
-
}
|
548 |
-
|
549 |
-
mcrypt_module_close($this->encryptStream);
|
550 |
-
|
551 |
-
$this->encryptStream = false;
|
552 |
-
}
|
553 |
-
|
554 |
-
if ( $this->decryptStream !== false ) {
|
555 |
-
if ( $this->continuousBuffer ) {
|
556 |
-
mcrypt_generic_deinit($this->decryptStream);
|
557 |
-
}
|
558 |
-
|
559 |
-
mcrypt_module_close($this->decryptStream);
|
560 |
-
|
561 |
-
$this->decryptStream = false;
|
562 |
-
}
|
563 |
-
}
|
564 |
-
}
|
1 |
+
<?php
|
2 |
+
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Pure-PHP implementation of RC4.
|
6 |
+
*
|
7 |
+
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
8 |
+
*
|
9 |
+
* PHP versions 4 and 5
|
10 |
+
*
|
11 |
+
* Useful resources are as follows:
|
12 |
+
*
|
13 |
+
* - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
|
14 |
+
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
|
15 |
+
*
|
16 |
+
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
|
17 |
+
* ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
|
18 |
+
*
|
19 |
+
* Here's a short example of how to use this library:
|
20 |
+
* <code>
|
21 |
+
* <?php
|
22 |
+
* include('Crypt/RC4.php');
|
23 |
+
*
|
24 |
+
* $rc4 = new Crypt_RC4();
|
25 |
+
*
|
26 |
+
* $rc4->setKey('abcdefgh');
|
27 |
+
*
|
28 |
+
* $size = 10 * 1024;
|
29 |
+
* $plaintext = '';
|
30 |
+
* for ($i = 0; $i < $size; $i++) {
|
31 |
+
* $plaintext.= 'a';
|
32 |
+
* }
|
33 |
+
*
|
34 |
+
* echo $rc4->decrypt($rc4->encrypt($plaintext));
|
35 |
+
* ?>
|
36 |
+
* </code>
|
37 |
+
*
|
38 |
+
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
39 |
+
* of this software and associated documentation files (the "Software"), to deal
|
40 |
+
* in the Software without restriction, including without limitation the rights
|
41 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
42 |
+
* copies of the Software, and to permit persons to whom the Software is
|
43 |
+
* furnished to do so, subject to the following conditions:
|
44 |
+
*
|
45 |
+
* The above copyright notice and this permission notice shall be included in
|
46 |
+
* all copies or substantial portions of the Software.
|
47 |
+
*
|
48 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
49 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
50 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
51 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
52 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
53 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
54 |
+
* THE SOFTWARE.
|
55 |
+
*
|
56 |
+
* @category Crypt
|
57 |
+
* @package Crypt_RC4
|
58 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
59 |
+
* @copyright MMVII Jim Wigginton
|
60 |
+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
61 |
+
* @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
|
62 |
+
* @link http://phpseclib.sourceforge.net
|
63 |
+
*/
|
64 |
+
|
65 |
+
/**#@+
|
66 |
+
* @access private
|
67 |
+
* @see Crypt_RC4::Crypt_RC4()
|
68 |
+
*/
|
69 |
+
/**
|
70 |
+
* Toggles the internal implementation
|
71 |
+
*/
|
72 |
+
define('CRYPT_RC4_MODE_INTERNAL', 1);
|
73 |
+
/**
|
74 |
+
* Toggles the mcrypt implementation
|
75 |
+
*/
|
76 |
+
define('CRYPT_RC4_MODE_MCRYPT', 2);
|
77 |
+
/**#@-*/
|
78 |
+
|
79 |
+
/**#@+
|
80 |
+
* @access private
|
81 |
+
* @see Crypt_RC4::_crypt()
|
82 |
+
*/
|
83 |
+
define('CRYPT_RC4_ENCRYPT', 0);
|
84 |
+
define('CRYPT_RC4_DECRYPT', 1);
|
85 |
+
/**#@-*/
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Pure-PHP implementation of RC4.
|
89 |
+
*
|
90 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
91 |
+
* @version 0.1.0
|
92 |
+
* @access public
|
93 |
+
* @package Crypt_RC4
|
94 |
+
*/
|
95 |
+
class Crypt_RC4 {
|
96 |
+
/**
|
97 |
+
* The Key
|
98 |
+
*
|
99 |
+
* @see Crypt_RC4::setKey()
|
100 |
+
* @var String
|
101 |
+
* @access private
|
102 |
+
*/
|
103 |
+
var $key = "\0";
|
104 |
+
|
105 |
+
/**
|
106 |
+
* The Key Stream for encryption
|
107 |
+
*
|
108 |
+
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
109 |
+
*
|
110 |
+
* @see Crypt_RC4::setKey()
|
111 |
+
* @var Array
|
112 |
+
* @access private
|
113 |
+
*/
|
114 |
+
var $encryptStream = false;
|
115 |
+
|
116 |
+
/**
|
117 |
+
* The Key Stream for decryption
|
118 |
+
*
|
119 |
+
* If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
|
120 |
+
*
|
121 |
+
* @see Crypt_RC4::setKey()
|
122 |
+
* @var Array
|
123 |
+
* @access private
|
124 |
+
*/
|
125 |
+
var $decryptStream = false;
|
126 |
+
|
127 |
+
/**
|
128 |
+
* The $i and $j indexes for encryption
|
129 |
+
*
|
130 |
+
* @see Crypt_RC4::_crypt()
|
131 |
+
* @var Integer
|
132 |
+
* @access private
|
133 |
+
*/
|
134 |
+
var $encryptIndex = 0;
|
135 |
+
|
136 |
+
/**
|
137 |
+
* The $i and $j indexes for decryption
|
138 |
+
*
|
139 |
+
* @see Crypt_RC4::_crypt()
|
140 |
+
* @var Integer
|
141 |
+
* @access private
|
142 |
+
*/
|
143 |
+
var $decryptIndex = 0;
|
144 |
+
|
145 |
+
/**
|
146 |
+
* The Encryption Algorithm
|
147 |
+
*
|
148 |
+
* Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT. Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.
|
149 |
+
*
|
150 |
+
* @see Crypt_RC4::Crypt_RC4()
|
151 |
+
* @var Integer
|
152 |
+
* @access private
|
153 |
+
*/
|
154 |
+
var $mode;
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Continuous Buffer status
|
158 |
+
*
|
159 |
+
* @see Crypt_RC4::enableContinuousBuffer()
|
160 |
+
* @var Boolean
|
161 |
+
* @access private
|
162 |
+
*/
|
163 |
+
var $continuousBuffer = false;
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Default Constructor.
|
167 |
+
*
|
168 |
+
* Determines whether or not the mcrypt extension should be used.
|
169 |
+
*
|
170 |
+
* @param optional Integer $mode
|
171 |
+
* @return Crypt_RC4
|
172 |
+
* @access public
|
173 |
+
*/
|
174 |
+
function Crypt_RC4()
|
175 |
+
{
|
176 |
+
if ( !defined('CRYPT_RC4_MODE') ) {
|
177 |
+
switch (true) {
|
178 |
+
case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')) && in_array('arcfour', mcrypt_list_algorithms()):
|
179 |
+
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);
|
180 |
+
break;
|
181 |
+
default:
|
182 |
+
define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
switch ( CRYPT_RC4_MODE ) {
|
187 |
+
case CRYPT_RC4_MODE_MCRYPT:
|
188 |
+
switch (true) {
|
189 |
+
case defined('MCRYPT_ARCFOUR'):
|
190 |
+
$this->mode = MCRYPT_ARCFOUR;
|
191 |
+
break;
|
192 |
+
case defined('MCRYPT_RC4');
|
193 |
+
$this->mode = MCRYPT_RC4;
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Sets the key.
|
200 |
+
*
|
201 |
+
* Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
|
202 |
+
* be used. If no key is explicitly set, it'll be assumed to be a single null byte.
|
203 |
+
*
|
204 |
+
* @access public
|
205 |
+
* @param String $key
|
206 |
+
*/
|
207 |
+
function setKey($key)
|
208 |
+
{
|
209 |
+
$this->key = $key;
|
210 |
+
|
211 |
+
if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
|
212 |
+
return;
|
213 |
+
}
|
214 |
+
|
215 |
+
$keyLength = strlen($key);
|
216 |
+
$keyStream = array();
|
217 |
+
for ($i = 0; $i < 256; $i++) {
|
218 |
+
$keyStream[$i] = $i;
|
219 |
+
}
|
220 |
+
$j = 0;
|
221 |
+
for ($i = 0; $i < 256; $i++) {
|
222 |
+
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
|
223 |
+
$temp = $keyStream[$i];
|
224 |
+
$keyStream[$i] = $keyStream[$j];
|
225 |
+
$keyStream[$j] = $temp;
|
226 |
+
}
|
227 |
+
|
228 |
+
$this->encryptIndex = $this->decryptIndex = array(0, 0);
|
229 |
+
$this->encryptStream = $this->decryptStream = $keyStream;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Sets the password.
|
234 |
+
*
|
235 |
+
* Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
|
236 |
+
* {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
|
237 |
+
* $hash, $salt, $count, $dkLen
|
238 |
+
*
|
239 |
+
* @param String $password
|
240 |
+
* @param optional String $method
|
241 |
+
* @access public
|
242 |
+
*/
|
243 |
+
function setPassword($password, $method = 'pbkdf2')
|
244 |
+
{
|
245 |
+
$key = '';
|
246 |
+
|
247 |
+
switch ($method) {
|
248 |
+
default: // 'pbkdf2'
|
249 |
+
list(, , $hash, $salt, $count) = func_get_args();
|
250 |
+
if (!isset($hash)) {
|
251 |
+
$hash = 'sha1';
|
252 |
+
}
|
253 |
+
// WPA and WPA use the SSID as the salt
|
254 |
+
if (!isset($salt)) {
|
255 |
+
$salt = 'phpseclib/salt';
|
256 |
+
}
|
257 |
+
// RFC2898#section-4.2 uses 1,000 iterations by default
|
258 |
+
// WPA and WPA2 use 4,096.
|
259 |
+
if (!isset($count)) {
|
260 |
+
$count = 1000;
|
261 |
+
}
|
262 |
+
if (!isset($dkLen)) {
|
263 |
+
$dkLen = 128;
|
264 |
+
}
|
265 |
+
|
266 |
+
if (!class_exists('Crypt_Hash')) {
|
267 |
+
require_once('Crypt/Hash.php');
|
268 |
+
}
|
269 |
+
|
270 |
+
$i = 1;
|
271 |
+
while (strlen($key) < $dkLen) {
|
272 |
+
//$dk.= $this->_pbkdf($password, $salt, $count, $i++);
|
273 |
+
$hmac = new Crypt_Hash();
|
274 |
+
$hmac->setHash($hash);
|
275 |
+
$hmac->setKey($password);
|
276 |
+
$f = $u = $hmac->hash($salt . pack('N', $i++));
|
277 |
+
for ($j = 2; $j <= $count; $j++) {
|
278 |
+
$u = $hmac->hash($u);
|
279 |
+
$f^= $u;
|
280 |
+
}
|
281 |
+
$key.= $f;
|
282 |
+
}
|
283 |
+
}
|
284 |
+
|
285 |
+
$this->setKey(substr($key, 0, $dkLen));
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Dummy function.
|
290 |
+
*
|
291 |
+
* Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
|
292 |
+
* If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
|
293 |
+
* calling setKey().
|
294 |
+
*
|
295 |
+
* [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
|
296 |
+
* the IV's are relatively easy to predict, an attack described by
|
297 |
+
* {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
|
298 |
+
* can be used to quickly guess at |