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