home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 April / PCWorld_2005-04_cd.bin / akce / web / phptriad / phptriad2-2-1.exe / php / pear / Crypt / HCEMD5.php < prev   
PHP Script  |  2001-08-02  |  10KB  |  289 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2001 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Manon Goo <manon@passionet.de>                              |
  17. // |          Chuck Hagenbuch <chuck@horde.org>                           |
  18. // +----------------------------------------------------------------------+
  19.  
  20. /**
  21. * Class to emulate Perl's Crypt::HCE_MD5 module
  22. * The MIME Functions are tested and work symmetrically with the
  23. * Crypt::HCE_MD5 package (0.45) (without the KEYBUG Flag ..).
  24. * Shamelessly stolen from Eric Estabrooks, eric@urbanrage.com
  25. * Crypt::HCE_MD5 package:
  26. * This package implements a chaining block cipher using a one way
  27. * hash. This method of encryption is the same that is used by radius
  28. * (RFC2138) and is also described in Applied Cryptography by Bruce
  29. * Schneider (p. 353 / "Karn").
  30. * Two interfaces are provided in the package. The first is straight
  31. * block encryption/decryption the second does base64 mime
  32. * encoding/decoding of the encrypted/decrypted blocks.
  33. * The idea is the the two sides have a shared secret that supplies one
  34. * of the keys and a randomly generated block of bytes provides the
  35. * second key. The random key is passed in cleartext between the two
  36. * sides.
  37. * Usage:
  38. * require_once 'Crypt/HCEMD5.php';
  39. * $key = 'my secret key';
  40. * srand((double)microtime()*32767);
  41. * $rand = rand(1, 32767);
  42. * $rand = pack('i*', $rand);
  43. * $message = 'text to encrypt';
  44. * $hcemd5 = new Crypt_HCEMD5($key, $rand);
  45. * // These Functions work with mime decoded Data
  46. * $ciphertext = $hcemd5->encodeMime($message);
  47. * $cleartext = $hcemd5->decodeMime($ciphertext);
  48. * // These Functions work with binary Data
  49. * $ciphertext = $hcemd5->encrypt($message);
  50. * $cleartext = $hcemd5->decrypt($ciphertext);
  51. * // These Functions work with mime decoded Data the selfrand
  52. * // functions put the random value infront of the encrypted data to
  53. * // be restored later
  54. * $ciphertext = $hcemd5->encodeMimeSelfRand($message);
  55. * $new_hcemd5 = new Crypt_HCEMD5($key, '');
  56. * $cleartext = $new_hcemd5->DecodeMimeSelfRand($ciphertext);
  57. *
  58. * @version $Id: HCEMD5.php,v 1.6 2001/08/02 15:23:00 alexmerz Exp $
  59. * @access public
  60. * @package Crypt
  61. */
  62. class Crypt_HCEMD5 {
  63.     
  64.     /**
  65.      * The first key to use. This should be a shared secret.
  66.      * @var string
  67.      */
  68.     var $key;
  69.     
  70.     /**
  71.      * The second key to use. This should be a randomly generated
  72.      * block of bytes.
  73.      * @var long
  74.      */
  75.     var $rand;
  76.     
  77.     
  78.     /**
  79.      * Creates a Crypt_HCEMD5 object.
  80.      *
  81.      * @param string The shared secret key
  82.      * @param long   (optional) The randomly generated key
  83.      *
  84.      * @access public
  85.      */
  86.     function Crypt_HCEMD5($key, $rand = null) {
  87.         $this->key = $key;
  88.         
  89.         if (!isset($rand)) {
  90.             srand((double)microtime() * 32767);
  91.             $rand = rand(1, 32767);
  92.             $rand = pack('i*', $rand);
  93.         }
  94.         $this->rand = $rand;
  95.     }
  96.     
  97.     
  98.     /**
  99.      * Encrypt a block of data.
  100.      *
  101.      * @param string The data to encrypt.
  102.      * @return string The encrypted binary data.
  103.      * @access public
  104.      */
  105.     function encrypt($data)
  106.     {
  107.         $data = unpack('C*', $data);
  108.         $ans = array();
  109.         $ans1 = array(); 
  110.         $eblock = 1;
  111.         $e_block = $this->newKey($this->rand);
  112.         $data_size = count($data);
  113.         for ($i = 0; $i < $data_size; $i++) {
  114.             $mod = $i % 16;
  115.             if (($mod == 0) && ($i > 15)) {
  116.                    $tmparr = array($ans[$i - 15],  $ans[$i - 14], $ans[$i - 13], $ans[$i - 12], $ans[$i - 11], $ans[$i - 10], $ans[$i - 9], $ans[$i - 8], $ans[$i - 7], $ans[$i - 6], $ans[$i - 5], $ans[$i - 4], $ans[$i - 3], $ans[$i - 2], $ans[$i - 1], $ans[$i] );
  117.                 $tmparr = $this->array2pack($tmparr);
  118.                 $tmparr = implode('', $tmparr);
  119.                 $e_block = $this->newKey($tmparr);
  120.             }
  121.             
  122.             $mod++;
  123.             $i++;
  124.             $ans[$i] = $e_block[$mod] ^ $data[$i];
  125.             $ans1[$i] = pack('C*', $ans[$i]);
  126.             $i--;
  127.             $mod--;
  128.         }
  129.         return implode('', $ans1);
  130.     }
  131.     
  132.     /**
  133.      * Decrypt a block of data.
  134.      *
  135.      * @param string The data to decrypt.
  136.      * @return string The decrypted binary data.
  137.      * @access public
  138.      */
  139.     function decrypt($data)
  140.     {
  141.         $data = unpack('C*', $data);
  142.         $ans = array();
  143.         $ans1 = array(); 
  144.         $eblock = 1;
  145.         $e_block = $this->newKey($this->rand);
  146.         $data_size = count($data);
  147.         for ($i = 0; $i < $data_size; $i++) {
  148.             $mod = $i % 16;
  149.             if (($mod == 0) && ($i > 15)) {
  150.                    $tmparr = array($data[$i - 15], $data[$i - 14], $data[$i - 13], $data[$i - 12], $data[$i - 11], $data[$i - 10], $data[$i - 9], $data[$i - 8], $data[$i - 7], $data[$i - 6], $data[$i - 5], $data[$i - 4], $data[$i - 3], $data[$i - 2], $data[$i - 1], $data[$i]);
  151.                 $tmparr = $this->array2pack($tmparr);
  152.                 $tmparr = implode('', $tmparr);
  153.                 $e_block = $this->newKey($tmparr);
  154.             }
  155.             
  156.             $mod++;
  157.             $i++;
  158.             $ans[$i] = $e_block[$mod] ^ $data[$i];
  159.             $ans1[$i] = pack('C*', $ans[$i]);
  160.             $i--;
  161.         }
  162.         return implode('', $ans1);
  163.     }
  164.     
  165.     /**
  166.      * Encrypt a block of data after MIME-encoding it.
  167.      *
  168.      * @param string The data to encrypt.
  169.      * @return string The encrypted mime-encoded data.
  170.      * @access public
  171.      */
  172.     function encodeMime($data)
  173.     {
  174.         return base64_encode($this->encrypt($data));
  175.     }
  176.     
  177.     /**
  178.      * Decrypt a block of data and then MIME-decode it.
  179.      *
  180.      * @param string The data to decrypt.
  181.      * @return string The decrypted mime-decoded data.
  182.      * @access public
  183.      */
  184.     function decodeMime($data)
  185.     {
  186.         return $this->decrypt(base64_decode($data));
  187.     }
  188.     
  189.     /**
  190.      * Encrypt a block of data after MIME-encoding it, and include the
  191.      * random hash in the final output in plaintext so it can be
  192.      * retrieved and decrypted with only the secret key by
  193.      * decodeMimeSelfRand().
  194.      *
  195.      * @param string The data to encrypt.
  196.      * @param string The encrypted mime-encoded data, in the format: randkey#encrypted_data.
  197.      * @access public
  198.      */
  199.     function encodeMimeSelfRand($data) {
  200.         return base64_encode($this->rand) . '#' . $this->encodeMime($data);
  201.     }
  202.     
  203.     /**
  204.      * Decrypt a block of data and then MIME-decode it, using the
  205.      * random key stored in beginning of the ciphertext generated by
  206.      * encodeMimeSelfRand().
  207.      *
  208.      * @param string The data to decrypt, in the format: randkey#encrypted_data.
  209.      * @return string The decrypted, mime-decoded data.
  210.      * @access public
  211.      */
  212.     function decodeMimeSelfRand($data)
  213.     {
  214.         if (strpos($data, '#') === false) {
  215.             return false;
  216.         }
  217.         
  218.         list($rand, $data_crypt) = explode('#', $data);
  219.         if (isset($data_crypt)) {
  220.             $rand = base64_decode($rand);
  221.             $this->rand = $rand;
  222.             return $this->decodeMime($data_crypt);
  223.         } else {
  224.             return false;
  225.         }
  226.     }
  227.     
  228.     
  229.     /**
  230.      ** Support Functions
  231.      **/
  232.     
  233.     /**
  234.      * Implment md5 hashing in php, though use the mhash() function if it is available.
  235.      *
  236.      * @param string The string to hash.
  237.      * @return string The md5 mhash of the string.
  238.      * @access private
  239.      */
  240.     function binmd5($string)
  241.     {
  242.         if (extension_loaded('mhash')) {
  243.             return mhash(MHASH_MD5, $string);
  244.         }
  245.         
  246.         return pack('H*', md5(pack('H*', preg_replace('|00$|', '', bin2hex($string)))));
  247.     }
  248.     
  249.     /**
  250.      * Turn an array into a binary packed string.
  251.      *
  252.      * @param array The array to pack.
  253.      * @return string The binary packed representation of the array.
  254.      * @access private
  255.      */
  256.     function array2pack($array)
  257.     {
  258.         $pack = array();
  259.         foreach ($array as $val) {
  260.             $pack[] = pack('C*', $val);
  261.         }
  262.         return $pack;
  263.     }
  264.     
  265.     /**
  266.      * Generate a new key for a new encryption block.
  267.      *
  268.      * @param string The basis for the key.
  269.      * @param string The new key.
  270.      * @access private
  271.      */
  272.     function newKey($round)
  273.     {
  274.         $digest = $this->binmd5($this->key . $round);
  275.         return unpack('C*', $digest);
  276.     }
  277.     
  278. }
  279. ?>
  280.