Posted By

jodm on 08/04/09


Tagged

Encryption blowfish


Versions (?)

Who likes this?

3 people have marked this snippet as a favorite

irishsk
umang_nine
BrianCoyDesign


Blowfish


 / Published in: PHP
 

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * Crypt_Blowfish allows for encryption and decryption on the fly using
  6.  * the Blowfish algorithm. Crypt_Blowfish does not require the mcrypt
  7.  * PHP extension, it uses only PHP.
  8.  * Crypt_Blowfish support encryption/decryption with or without a secret key.
  9.  *
  10.  *
  11.  * PHP versions 4 and 5
  12.  *
  13.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  14.  * that is available through the world-wide-web at the following URI:
  15.  * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  16.  * the PHP License and are unable to obtain it through the web, please
  17.  * send a note to [email protected] so we can mail you a copy immediately.
  18.  *
  19.  * @category Encryption
  20.  * @package Crypt_Blowfish
  21.  * @author Matthew Fonda <[email protected]>
  22.  * @copyright 2005 Matthew Fonda
  23.  * @license http://www.php.net/license/3_0.txt PHP License 3.0
  24.  * @version CVS: $Id: Blowfish.php,v 1.81 2005/05/30 18:40:36 mfonda Exp $
  25.  * @link http://pear.php.net/package/Crypt_Blowfish
  26.  */
  27.  
  28.  
  29. require_once 'PEAR.php';
  30.  
  31.  
  32. /**
  33.  *
  34.  * Example usage:
  35.  * $bf = new Crypt_Blowfish('some secret key!');
  36.  * $encrypted = $bf->encrypt('this is some example plain text');
  37.  * $plaintext = $bf->decrypt($encrypted);
  38.  * echo "plain text: $plaintext";
  39.  *
  40.  *
  41.  * @category Encryption
  42.  * @package Crypt_Blowfish
  43.  * @author Matthew Fonda <[email protected]>
  44.  * @copyright 2005 Matthew Fonda
  45.  * @license http://www.php.net/license/3_0.txt PHP License 3.0
  46.  * @link http://pear.php.net/package/Crypt_Blowfish
  47.  * @version @package_version@
  48.  * @access public
  49.  */
  50. class Crypt_Blowfish
  51. {
  52. /**
  53.   * P-Array contains 18 32-bit subkeys
  54.   *
  55.   * @var array
  56.   * @access private
  57.   */
  58. var $_P = array();
  59.  
  60.  
  61. /**
  62.   * Array of four S-Blocks each containing 256 32-bit entries
  63.   *
  64.   * @var array
  65.   * @access private
  66.   */
  67. var $_S = array();
  68.  
  69. /**
  70.   * Mcrypt td resource
  71.   *
  72.   * @var resource
  73.   * @access private
  74.   */
  75. var $_td = null;
  76.  
  77. /**
  78.   * Initialization vector
  79.   *
  80.   * @var string
  81.   * @access private
  82.   */
  83. var $_iv = null;
  84.  
  85.  
  86. /**
  87.   * Crypt_Blowfish Constructor
  88.   * Initializes the Crypt_Blowfish object, and gives a sets
  89.   * the secret key
  90.   *
  91.   * @param string $key
  92.   * @access public
  93.   */
  94. function Crypt_Blowfish($key)
  95. {
  96. if (extension_loaded('mcrypt')) {
  97. $this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
  98. $this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
  99. }
  100. $this->setKey($key);
  101. }
  102.  
  103. /**
  104.   * Deprecated isReady method
  105.   *
  106.   * @return bool
  107.   * @access public
  108.   * @deprecated
  109.   */
  110. function isReady()
  111. {
  112. return true;
  113. }
  114.  
  115. /**
  116.   * Deprecated init method - init is now a private
  117.   * method and has been replaced with _init
  118.   *
  119.   * @return bool
  120.   * @access public
  121.   * @deprecated
  122.   * @see Crypt_Blowfish::_init()
  123.   */
  124. function init()
  125. {
  126. $this->_init();
  127. }
  128.  
  129. /**
  130.   * Initializes the Crypt_Blowfish object
  131.   *
  132.   * @access private
  133.   */
  134. function _init()
  135. {
  136. $defaults = new Crypt_Blowfish_DefaultKey();
  137. $this->_P = $defaults->P;
  138. $this->_S = $defaults->S;
  139. }
  140.  
  141. /**
  142.   * Enciphers a single 64 bit block
  143.   *
  144.   * @param int &$Xl
  145.   * @param int &$Xr
  146.   * @access private
  147.   */
  148. function _encipher(&$Xl, &$Xr)
  149. {
  150. for ($i = 0; $i < 16; $i++) {
  151. $temp = $Xl ^ $this->_P[$i];
  152. $Xl = ((($this->_S[0][($temp>>24) & 255] +
  153. $this->_S[1][($temp>>16) & 255]) ^
  154. $this->_S[2][($temp>>8) & 255]) +
  155. $this->_S[3][$temp & 255]) ^ $Xr;
  156. $Xr = $temp;
  157. }
  158. $Xr = $Xl ^ $this->_P[16];
  159. $Xl = $temp ^ $this->_P[17];
  160. }
  161.  
  162.  
  163. /**
  164.   * Deciphers a single 64 bit block
  165.   *
  166.   * @param int &$Xl
  167.   * @param int &$Xr
  168.   * @access private
  169.   */
  170. function _decipher(&$Xl, &$Xr)
  171. {
  172. for ($i = 17; $i > 1; $i--) {
  173. $temp = $Xl ^ $this->_P[$i];
  174. $Xl = ((($this->_S[0][($temp>>24) & 255] +
  175. $this->_S[1][($temp>>16) & 255]) ^
  176. $this->_S[2][($temp>>8) & 255]) +
  177. $this->_S[3][$temp & 255]) ^ $Xr;
  178. $Xr = $temp;
  179. }
  180. $Xr = $Xl ^ $this->_P[1];
  181. $Xl = $temp ^ $this->_P[0];
  182. }
  183.  
  184.  
  185. /**
  186.   * Encrypts a string
  187.   *
  188.   * @param string $plainText
  189.   * @return string Returns cipher text on success, PEAR_Error on failure
  190.   * @access public
  191.   */
  192. function encrypt($plainText)
  193. {
  194. if (!is_string($plainText)) {
  195. PEAR::raiseError('Plain text must be a string', 0, PEAR_ERROR_DIE);
  196. }
  197.  
  198. if (extension_loaded('mcrypt')) {
  199. return mcrypt_generic($this->_td, $plainText);
  200. }
  201.  
  202. $cipherText = '';
  203. $len = strlen($plainText);
  204. $plainText .= str_repeat(chr(0),(8 - ($len%8))%8);
  205. for ($i = 0; $i < $len; $i += 8) {
  206. list(,$Xl,$Xr) = unpack("N2",substr($plainText,$i,8));
  207. $this->_encipher($Xl, $Xr);
  208. $cipherText .= pack("N2", $Xl, $Xr);
  209. }
  210. return $cipherText;
  211. }
  212.  
  213.  
  214. /**
  215.   * Decrypts an encrypted string
  216.   *
  217.   * @param string $cipherText
  218.   * @return string Returns plain text on success, PEAR_Error on failure
  219.   * @access public
  220.   */
  221. function decrypt($cipherText)
  222. {
  223. if (!is_string($cipherText)) {
  224. PEAR::raiseError('Chiper text must be a string', 1, PEAR_ERROR_DIE);
  225. }
  226.  
  227. if (extension_loaded('mcrypt')) {
  228. return mdecrypt_generic($this->_td, $cipherText);
  229. }
  230.  
  231. $plainText = '';
  232. $len = strlen($cipherText);
  233. $cipherText .= str_repeat(chr(0),(8 - ($len%8))%8);
  234. for ($i = 0; $i < $len; $i += 8) {
  235. list(,$Xl,$Xr) = unpack("N2",substr($cipherText,$i,8));
  236. $this->_decipher($Xl, $Xr);
  237. $plainText .= pack("N2", $Xl, $Xr);
  238. }
  239. return $plainText;
  240. }
  241.  
  242.  
  243. /**
  244.   * Sets the secret key
  245.   * The key must be non-zero, and less than or equal to
  246.   * 56 characters in length.
  247.   *
  248.   * @param string $key
  249.   * @return bool Returns true on success, PEAR_Error on failure
  250.   * @access public
  251.   */
  252. function setKey($key)
  253. {
  254. if (!is_string($key)) {
  255. PEAR::raiseError('Key must be a string', 2, PEAR_ERROR_DIE);
  256. }
  257.  
  258. $len = strlen($key);
  259.  
  260. if ($len > 56 || $len == 0) {
  261. PEAR::raiseError('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len, 3, PEAR_ERROR_DIE);
  262. }
  263.  
  264. if (extension_loaded('mcrypt')) {
  265. mcrypt_generic_init($this->_td, $key, $this->_iv);
  266. return true;
  267. }
  268.  
  269. require_once 'Blowfish/DefaultKey.php';
  270. $this->_init();
  271.  
  272. $k = 0;
  273. $data = 0;
  274. $datal = 0;
  275. $datar = 0;
  276.  
  277. for ($i = 0; $i < 18; $i++) {
  278. $data = 0;
  279. for ($j = 4; $j > 0; $j--) {
  280. $data = $data << 8 | ord($key{$k});
  281. $k = ($k+1) % $len;
  282. }
  283. $this->_P[$i] ^= $data;
  284. }
  285.  
  286. for ($i = 0; $i <= 16; $i += 2) {
  287. $this->_encipher($datal, $datar);
  288. $this->_P[$i] = $datal;
  289. $this->_P[$i+1] = $datar;
  290. }
  291. for ($i = 0; $i < 256; $i += 2) {
  292. $this->_encipher($datal, $datar);
  293. $this->_S[0][$i] = $datal;
  294. $this->_S[0][$i+1] = $datar;
  295. }
  296. for ($i = 0; $i < 256; $i += 2) {
  297. $this->_encipher($datal, $datar);
  298. $this->_S[1][$i] = $datal;
  299. $this->_S[1][$i+1] = $datar;
  300. }
  301. for ($i = 0; $i < 256; $i += 2) {
  302. $this->_encipher($datal, $datar);
  303. $this->_S[2][$i] = $datal;
  304. $this->_S[2][$i+1] = $datar;
  305. }
  306. for ($i = 0; $i < 256; $i += 2) {
  307. $this->_encipher($datal, $datar);
  308. $this->_S[3][$i] = $datal;
  309. $this->_S[3][$i+1] = $datar;
  310. }
  311.  
  312. return true;
  313. }
  314.  
  315. }
  316.  
  317. ?>

Report this snippet  

You need to login to post a comment.