123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- <?php
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
- /**
- * Crypt_Blowfish allows for encryption and decryption on the fly using
- * the Blowfish algorithm. Crypt_Blowfish does not require the mcrypt
- * PHP extension, it uses only PHP.
- * Crypt_Blowfish support encryption/decryption with or without a secret key.
- *
- *
- * PHP versions 4 and 5
- *
- * LICENSE: This source file is subject to version 3.0 of the PHP license
- * that is available through the world-wide-web at the following URI:
- * http://www.php.net/license/3_0.txt. If you did not receive a copy of
- * the PHP License and are unable to obtain it through the web, please
- * send a note to license@php.net so we can mail you a copy immediately.
- *
- * @category Encryption
- * @package Crypt_Blowfish
- * @author Matthew Fonda <mfonda@php.net>
- * @copyright 2005 Matthew Fonda
- * @license http://www.php.net/license/3_0.txt PHP License 3.0
- * @version CVS: $Id: Blowfish.php,v 1.81 2005/05/30 18:40:36 mfonda Exp $
- * @link http://pear.php.net/package/Crypt_Blowfish
- */
- require_once 'PEAR.php';
- /**
- *
- * Example usage:
- * $bf = new Crypt_Blowfish('some secret key!');
- * $encrypted = $bf->encrypt('this is some example plain text');
- * $plaintext = $bf->decrypt($encrypted);
- * echo "plain text: $plaintext";
- *
- *
- * @category Encryption
- * @package Crypt_Blowfish
- * @author Matthew Fonda <mfonda@php.net>
- * @copyright 2005 Matthew Fonda
- * @license http://www.php.net/license/3_0.txt PHP License 3.0
- * @link http://pear.php.net/package/Crypt_Blowfish
- * @version @package_version@
- * @access public
- */
- class Crypt_Blowfish
- {
- /**
- * P-Array contains 18 32-bit subkeys
- *
- * @var array
- * @access private
- */
- var $_P = array();
-
-
- /**
- * Array of four S-Blocks each containing 256 32-bit entries
- *
- * @var array
- * @access private
- */
- var $_S = array();
- /**
- * Mcrypt td resource
- *
- * @var resource
- * @access private
- */
- var $_td = null;
- /**
- * Initialization vector
- *
- * @var string
- * @access private
- */
- var $_iv = null;
-
- /**
- * Crypt_Blowfish Constructor
- * Initializes the Crypt_Blowfish object, and gives a sets
- * the secret key
- *
- * @param string $key
- * @access public
- */
- function Crypt_Blowfish($key)
- {
- if (extension_loaded('mcrypt')) {
- $this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
- $this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
- }
- $this->setKey($key);
- }
-
- /**
- * Deprecated isReady method
- *
- * @return bool
- * @access public
- * @deprecated
- */
- function isReady()
- {
- return true;
- }
-
- /**
- * Deprecated init method - init is now a private
- * method and has been replaced with _init
- *
- * @return bool
- * @access public
- * @deprecated
- * @see Crypt_Blowfish::_init()
- */
- function init()
- {
- $this->_init();
- }
-
- /**
- * Initializes the Crypt_Blowfish object
- *
- * @access private
- */
- function _init()
- {
- $defaults = new Crypt_Blowfish_DefaultKey();
- $this->_P = $defaults->P;
- $this->_S = $defaults->S;
- }
-
- /**
- * Enciphers a single 64 bit block
- *
- * @param int &$Xl
- * @param int &$Xr
- * @access private
- */
- function _encipher(&$Xl, &$Xr)
- {
- for ($i = 0; $i < 16; $i++) {
- $temp = $Xl ^ $this->_P[$i];
- $Xl = ((($this->_S[0][($temp>>24) & 255] +
- $this->_S[1][($temp>>16) & 255]) ^
- $this->_S[2][($temp>>8) & 255]) +
- $this->_S[3][$temp & 255]) ^ $Xr;
- $Xr = $temp;
- }
- $Xr = $Xl ^ $this->_P[16];
- $Xl = $temp ^ $this->_P[17];
- }
-
-
- /**
- * Deciphers a single 64 bit block
- *
- * @param int &$Xl
- * @param int &$Xr
- * @access private
- */
- function _decipher(&$Xl, &$Xr)
- {
- for ($i = 17; $i > 1; $i--) {
- $temp = $Xl ^ $this->_P[$i];
- $Xl = ((($this->_S[0][($temp>>24) & 255] +
- $this->_S[1][($temp>>16) & 255]) ^
- $this->_S[2][($temp>>8) & 255]) +
- $this->_S[3][$temp & 255]) ^ $Xr;
- $Xr = $temp;
- }
- $Xr = $Xl ^ $this->_P[1];
- $Xl = $temp ^ $this->_P[0];
- }
-
-
- /**
- * Encrypts a string
- *
- * @param string $plainText
- * @return string Returns cipher text on success, PEAR_Error on failure
- * @access public
- */
- function encrypt($plainText)
- {
- if (!is_string($plainText)) {
- PEAR::raiseError('Plain text must be a string', 0, PEAR_ERROR_DIE);
- }
- if (extension_loaded('mcrypt')) {
- return mcrypt_generic($this->_td, $plainText);
- }
- $cipherText = '';
- $len = strlen($plainText);
- $plainText .= str_repeat(chr(0),(8 - ($len%8))%8);
- for ($i = 0; $i < $len; $i += 8) {
- list(,$Xl,$Xr) = unpack("N2",substr($plainText,$i,8));
- $this->_encipher($Xl, $Xr);
- $cipherText .= pack("N2", $Xl, $Xr);
- }
- return $cipherText;
- }
-
-
- /**
- * Decrypts an encrypted string
- *
- * @param string $cipherText
- * @return string Returns plain text on success, PEAR_Error on failure
- * @access public
- */
- function decrypt($cipherText)
- {
- if (!is_string($cipherText)) {
- PEAR::raiseError('Cipher text must be a string', 1, PEAR_ERROR_DIE);
- }
- if (extension_loaded('mcrypt')) {
- return mdecrypt_generic($this->_td, $cipherText);
- }
- $plainText = '';
- $len = strlen($cipherText);
- $cipherText .= str_repeat(chr(0),(8 - ($len%8))%8);
- for ($i = 0; $i < $len; $i += 8) {
- list(,$Xl,$Xr) = unpack("N2",substr($cipherText,$i,8));
- $this->_decipher($Xl, $Xr);
- $plainText .= pack("N2", $Xl, $Xr);
- }
- return $plainText;
- }
-
-
- /**
- * Sets the secret key
- * The key must be non-zero, and less than or equal to
- * 56 characters in length.
- *
- * @param string $key
- * @return bool Returns true on success, PEAR_Error on failure
- * @access public
- */
- function setKey($key)
- {
- if (!is_string($key)) {
- PEAR::raiseError('Key must be a string', 2, PEAR_ERROR_DIE);
- }
- $len = strlen($key);
- if ($len > 56 || $len == 0) {
- PEAR::raiseError('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len, 3, PEAR_ERROR_DIE);
- }
- if (extension_loaded('mcrypt')) {
- mcrypt_generic_init($this->_td, $key, $this->_iv);
- return true;
- }
- require_once 'Blowfish/DefaultKey.php';
- $this->_init();
-
- $k = 0;
- $data = 0;
- $datal = 0;
- $datar = 0;
-
- for ($i = 0; $i < 18; $i++) {
- $data = 0;
- for ($j = 4; $j > 0; $j--) {
- $data = $data << 8 | ord($key{$k});
- $k = ($k+1) % $len;
- }
- $this->_P[$i] ^= $data;
- }
-
- for ($i = 0; $i <= 16; $i += 2) {
- $this->_encipher($datal, $datar);
- $this->_P[$i] = $datal;
- $this->_P[$i+1] = $datar;
- }
- for ($i = 0; $i < 256; $i += 2) {
- $this->_encipher($datal, $datar);
- $this->_S[0][$i] = $datal;
- $this->_S[0][$i+1] = $datar;
- }
- for ($i = 0; $i < 256; $i += 2) {
- $this->_encipher($datal, $datar);
- $this->_S[1][$i] = $datal;
- $this->_S[1][$i+1] = $datar;
- }
- for ($i = 0; $i < 256; $i += 2) {
- $this->_encipher($datal, $datar);
- $this->_S[2][$i] = $datal;
- $this->_S[2][$i+1] = $datar;
- }
- for ($i = 0; $i < 256; $i += 2) {
- $this->_encipher($datal, $datar);
- $this->_S[3][$i] = $datal;
- $this->_S[3][$i+1] = $datar;
- }
-
- return true;
- }
-
- }
- ?>
|