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 / CBC.php next >
PHP Script  |  2001-12-20  |  9KB  |  319 lines

  1. <?php
  2. /* vim: set ts=4 sw=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 2001 The PHP Group                                     |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 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: Colin Viebrock <colin@easydns.com>                          |
  17. // |          Mike Glover <mpg4@duluoz.net>                               |
  18. // +----------------------------------------------------------------------+
  19. //
  20.  
  21. require_once 'PEAR.php';
  22.  
  23.  
  24. /**
  25. * Class to emulate Perl's Crypt::CBC module
  26. *
  27. * Blowfish support is not completely working, mainly because of a bug
  28. * discovered in libmcrypt (version 2.4.8 and earlier).  If you are running
  29. * a later version of libmcrypt > 2.4.8, you can do Blowfish encryption
  30. * that is compatable with Perl.  However, check the libmcrypt documenation
  31. * as to whether you should use 'BLOWFISH' or 'BLOWFISH-COMPAT' when
  32. * specifying the cipher.
  33. *
  34. * If you are using libmcrypt <= 2.4.8, Blowfish encryption will work,
  35. * but your data will not be readable by Perl scripts.  It will work
  36. * "internally" .. i.e. this class will be able to encode/decode the data.
  37. *
  38. * This class will no longer work with libmcrypt 2.2.x versions.
  39. *
  40. * NOTE: the cipher names in this class may change depending on how
  41. * the author of libcrypt decides to name things internally.
  42. *
  43. *
  44. * @version  $Id: CBC.php,v 1.9.2.3 2001/12/20 17:29:21 cmv Exp $
  45. * @author   Colin Viebrock <colin@easydns.com>
  46. * @author   Mike Glover <mpg4@duluoz.net>
  47. * @access   public
  48. * @package Crypt
  49. */
  50.  
  51. class Crypt_CBC extends PEAR {
  52.  
  53.     /**
  54.     * supported procedures
  55.     * @var array
  56.     */
  57.     var $known_ciphers = array (
  58.         'DES'               => MCRYPT_DES,
  59.         'BLOWFISH'          => MCRYPT_BLOWFISH,
  60.         'BLOWFISH-COMPAT'   => MCRYPT_BLOWFISH_COMPAT,
  61.     );
  62.  
  63.     /**
  64.     * used cipher
  65.     * @var string
  66.     */
  67.     var $cipher;
  68.  
  69.     /**
  70.     * crypt resource, for 2.4.x
  71.     * @var string
  72.     */  
  73.     var $TD;
  74.  
  75.     /**
  76.     * blocksize of cipher
  77.     * @var string
  78.     */    
  79.     var $blocksize;
  80.  
  81.     /**
  82.     * keysize of cipher
  83.     * @var int
  84.     */    
  85.     var $keysize;
  86.  
  87.     /**
  88.     * mangled key
  89.     * @var string
  90.     */        
  91.     var $keyhash;
  92.  
  93.     /**
  94.     * source type of the initialization vector for creation  
  95.     * possible types are MCRYPT_RAND or MCRYPT_DEV_URANDOM or MCRYPT_DEV_RANDOM    
  96.     * @var int
  97.     */            
  98.     var $rand_source    = MCRYPT_RAND;
  99.  
  100.     /**
  101.     * header
  102.     * @var string
  103.     */           
  104.     var $header_spec    = 'RandomIV';
  105.  
  106.     /**
  107.     * debugging
  108.     * @var string
  109.     */           
  110.     var $_last_clear;
  111.  
  112.     /**
  113.     * debugging
  114.     * @var string
  115.     */              
  116.     var $_last_crypt;
  117.  
  118.     /**
  119.     * Constructor
  120.     * $key is the key to use for encryption. $cipher can be DES, BLOWFISH or
  121.     * BLOWFISH-COMPAT
  122.     *
  123.     * @param    $key        encryption key
  124.     * @param    $cipher     which algorithm to use, defaults to DES
  125.     *
  126.     * @return   $return     either a PEAR error or true
  127.     *
  128.     * @access   public
  129.     *
  130.     */
  131.  
  132.     function Crypt_CBC ($key, $cipher='DES')
  133.     {
  134.  
  135.         if (!extension_loaded('mcrypt')) {
  136.             return $this->raiseError('mcrypt module is not compiled into PHP', null, 
  137.                 PEAR_ERROR_DIE, null, 'compile PHP using "--with-mcrypt"' );
  138.         }
  139.         if (!function_exists('mcrypt_module_open')) {
  140.             return $this->raiseError('libmcrypt is 2.2.x', null, 
  141.                 PEAR_ERROR_DIE, null, 'this class only works with libmcrypt 2.4.x and later' );
  142.         }
  143.  
  144.         /* seed randomizer */
  145.  
  146.         srand ((double)microtime()*1000000);
  147.  
  148.         /* initialize */
  149.  
  150.         $this->header_spec = 'RandomIV';
  151.  
  152.         /* check for key */
  153.  
  154.         if (!$key) {
  155.             return $this->raiseError('no key specified');
  156.         }
  157.  
  158.         /* check for cipher */
  159.  
  160.         $cipher = strtoupper($cipher);
  161.         if (!isset($this->known_ciphers[$cipher])) {
  162.             return $this->raiseError('unknown cipher "'.$cipher.'"' );
  163.         }
  164.  
  165.         $this->cipher = $this->known_ciphers[$cipher];
  166.  
  167.         /* initialize cipher */
  168.  
  169.         $this->blocksize = mcrypt_get_block_size($this->cipher,'cbc');
  170.         $this->keysize = mcrypt_get_key_size($this->cipher,'cbc');
  171.         $this->TD = mcrypt_module_open ($this->cipher, '', 'ecb', '');
  172.  
  173.         /* mangle key with MD5 */
  174.  
  175.         $this->keyhash = $this->_md5perl($key);
  176.         while( strlen($this->keyhash) < $this->keysize ) {
  177.             $this->keyhash .= $this->_md5perl($this->keyhash);
  178.         }
  179.  
  180.         $this->key = substr($this->keyhash, 0, $this->keysize);
  181.  
  182.         return true;
  183.  
  184.     }
  185.  
  186.  
  187.     /**
  188.     * Destructor
  189.     *
  190.     */
  191.  
  192.     function _Crypt_CBC ()
  193.     {
  194.         @mcrypt_generic_end($this->TD);
  195.         @mcrypt_module_close($this->TD);
  196.     }
  197.  
  198.  
  199.     /**
  200.     * Encryption method
  201.     *
  202.     * @param    $clear      plaintext
  203.     *
  204.     * @return   $crypt      encrypted text, or PEAR error
  205.     *
  206.     * @access   public
  207.     *
  208.     */
  209.  
  210.     function encrypt($clear)
  211.     {
  212.  
  213.         $this->last_clear = $clear;
  214.  
  215.         /* new IV for each message */
  216.  
  217.         $iv = mcrypt_create_iv($this->blocksize, $this->rand_source);
  218.  
  219.         /* create the message header */
  220.  
  221.         $crypt = $this->header_spec . $iv;
  222.  
  223.         /* pad the cleartext */
  224.  
  225.         $padsize = $this->blocksize - (strlen($clear) % $this->blocksize);
  226.         $clear .= str_repeat(pack ('C*', $padsize), $padsize);
  227.  
  228.  
  229.         /* do the encryption */
  230.  
  231.         $start = 0;
  232.         while ( $block = substr($clear, $start, $this->blocksize) ) {
  233.             $start += $this->blocksize;
  234.             if (mcrypt_generic_init($this->TD, $this->key, $iv) < 0 ) {
  235.                 return $this->raiseError('mcrypt_generic_init failed' );
  236.             }
  237.             $cblock = mcrypt_generic($this->TD, $iv^$block );
  238.             $iv = $cblock;
  239.             $crypt .= $cblock;
  240.         }
  241.  
  242.         $this->last_crypt = $crypt;
  243.         return $crypt;
  244.  
  245.     }
  246.  
  247.  
  248.  
  249.     /**
  250.     * Decryption method
  251.     *
  252.     * @param    $crypt      encrypted text
  253.     *
  254.     * @return   $clear      plaintext, or PEAR error
  255.     *
  256.     * @access   public
  257.     *
  258.     */
  259.  
  260.     function decrypt($crypt) {
  261.  
  262.         $this->last_crypt = $crypt;
  263.  
  264.         /* get the IV from the message header */
  265.  
  266.         $iv_offset = strlen($this->header_spec);
  267.         $header = substr($crypt, 0, $iv_offset);
  268.         $iv = substr ($crypt, $iv_offset, $this->blocksize);
  269.         if ( $header != $this->header_spec ) {
  270.             return $this->raiseError('no initialization vector');
  271.         }
  272.  
  273.         $crypt = substr($crypt, $iv_offset+$this->blocksize);
  274.  
  275.         /* decrypt the message */
  276.  
  277.         $start = 0;
  278.         $clear = '';
  279.  
  280.         while ( $cblock = substr($crypt, $start, $this->blocksize) ) {
  281.             $start += $this->blocksize;
  282.             if (mcrypt_generic_init($this->TD, $this->key, $iv) < 0 ) {
  283.                 return $this->raiseError('mcrypt_generic_init failed' );
  284.             }
  285.             $block = $iv ^ mdecrypt_generic($this->TD, $cblock);
  286.             $iv = $cblock;
  287.             $clear .= $block;
  288.         }
  289.  
  290.         /* remove the padding from the end of the cleartext */
  291.  
  292.         $padsize = ord(substr($clear, -1));
  293.         $clear = substr($clear, 0, -$padsize);
  294.  
  295.         $this->last_clear = $clear;
  296.         return $clear;
  297.  
  298.     }
  299.  
  300.  
  301.  
  302.     /**
  303.     * Emulate Perl's MD5 function, which returns binary data
  304.     *
  305.     * @param    $string     string to MD5
  306.     *
  307.     * @return   $hash       binary hash
  308.     *
  309.     * @access private
  310.     *
  311.     */
  312.  
  313.     function _md5perl($string)
  314.     {
  315.         return pack('H*', md5($string));
  316.     }
  317. }
  318. ?>
  319.