PageRenderTime 728ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/system/libraries/Encrypt.php

https://github.com/holsinger/openfloor
PHP | 397 lines | 158 code | 53 blank | 186 comment | 22 complexity | bcc1716367d101e9a6e8e28688d006cc MD5 | raw file
  1. <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 4.3.2 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author Rick Ellis
  9. * @copyright Copyright (c) 2006, EllisLab, Inc.
  10. * @license http://www.codeignitor.com/user_guide/license.html
  11. * @link http://www.codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * CodeIgniter Encryption Class
  18. *
  19. * Provides two-way keyed encoding using XOR Hashing and Mcrypt
  20. *
  21. * @package CodeIgniter
  22. * @subpackage Libraries
  23. * @category Libraries
  24. * @author Rick Ellis
  25. * @link http://www.codeigniter.com/user_guide/libraries/encryption.html
  26. */
  27. class CI_Encrypt {
  28. var $encryption_key = '';
  29. var $_hash_type = 'sha1';
  30. var $_mcrypt_exists = FALSE;
  31. var $_mcrypt_cipher;
  32. var $_mcrypt_mode;
  33. /**
  34. * Constructor
  35. *
  36. * Simply determines whether the mcrypt library exists.
  37. *
  38. */
  39. function CI_Encrypt()
  40. {
  41. $this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;
  42. log_message('debug', "Encrypt Class Initialized");
  43. }
  44. // --------------------------------------------------------------------
  45. /**
  46. * Fetch the encryption key
  47. *
  48. * Returns it as MD5 in order to have an exact-length 128 bit key.
  49. * Mcrypt is sensitive to keys that are not the correct length
  50. *
  51. * @access public
  52. * @param string
  53. * @return string
  54. */
  55. function get_key($key = '')
  56. {
  57. if ($key == '')
  58. {
  59. if ($this->encryption_key != '')
  60. {
  61. return $this->encryption_key;
  62. }
  63. $CI =& get_instance();
  64. $key = $CI->config->item('encryption_key');
  65. if ($key === FALSE)
  66. {
  67. show_error('In order to use the encryption class requires that you set an encryption key in your config file.');
  68. }
  69. }
  70. return md5($key);
  71. }
  72. // --------------------------------------------------------------------
  73. /**
  74. * Set the encryption key
  75. *
  76. * @access public
  77. * @param string
  78. * @return void
  79. */
  80. function set_key($key = '')
  81. {
  82. $this->encryption_key = $key;
  83. }
  84. // --------------------------------------------------------------------
  85. /**
  86. * Encode
  87. *
  88. * Encodes the message string using bitwise XOR encoding.
  89. * The key is combined with a random hash, and then it
  90. * too gets converted using XOR. The whole thing is then run
  91. * through mcrypt (if supported) using the randomized key.
  92. * The end result is a double-encrypted message string
  93. * that is randomized with each call to this function,
  94. * even if the supplied message and key are the same.
  95. *
  96. * @access public
  97. * @param string the string to encode
  98. * @param string the key
  99. * @return string
  100. */
  101. function encode($string, $key = '')
  102. {
  103. $key = $this->get_key($key);
  104. $enc = $this->_xor_encode($string, $key);
  105. if ($this->_mcrypt_exists === TRUE)
  106. {
  107. $enc = $this->mcrypt_encode($enc, $key);
  108. }
  109. return base64_encode($enc);
  110. }
  111. // --------------------------------------------------------------------
  112. /**
  113. * Decode
  114. *
  115. * Reverses the above process
  116. *
  117. * @access public
  118. * @param string
  119. * @param string
  120. * @return string
  121. */
  122. function decode($string, $key = '')
  123. {
  124. $key = $this->get_key($key);
  125. $dec = base64_decode($string);
  126. if ($dec === FALSE)
  127. {
  128. return FALSE;
  129. }
  130. if ($this->_mcrypt_exists === TRUE)
  131. {
  132. $dec = $this->mcrypt_decode($dec, $key);
  133. }
  134. return $this->_xor_decode($dec, $key);
  135. }
  136. // --------------------------------------------------------------------
  137. /**
  138. * XOR Encode
  139. *
  140. * Takes a plain-text string and key as input and generates an
  141. * encoded bit-string using XOR
  142. *
  143. * @access private
  144. * @param string
  145. * @param string
  146. * @return string
  147. */
  148. function _xor_encode($string, $key)
  149. {
  150. $rand = '';
  151. while (strlen($rand) < 32)
  152. {
  153. $rand .= mt_rand(0, mt_getrandmax());
  154. }
  155. $rand = $this->hash($rand);
  156. $enc = '';
  157. for ($i = 0; $i < strlen($string); $i++)
  158. {
  159. $enc .= substr($rand, ($i % strlen($rand)), 1).(substr($rand, ($i % strlen($rand)), 1) ^ substr($string, $i, 1));
  160. }
  161. return $this->_xor_merge($enc, $key);
  162. }
  163. // --------------------------------------------------------------------
  164. /**
  165. * XOR Decode
  166. *
  167. * Takes an encoded string and key as input and generates the
  168. * plain-text original message
  169. *
  170. * @access private
  171. * @param string
  172. * @param string
  173. * @return string
  174. */
  175. function _xor_decode($string, $key)
  176. {
  177. $string = $this->_xor_merge($string, $key);
  178. $dec = '';
  179. for ($i = 0; $i < strlen($string); $i++)
  180. {
  181. $dec .= (substr($string, $i++, 1) ^ substr($string, $i, 1));
  182. }
  183. return $dec;
  184. }
  185. // --------------------------------------------------------------------
  186. /**
  187. * XOR key + string Combiner
  188. *
  189. * Takes a string and key as input and computes the difference using XOR
  190. *
  191. * @access private
  192. * @param string
  193. * @param string
  194. * @return string
  195. */
  196. function _xor_merge($string, $key)
  197. {
  198. $hash = $this->hash($key);
  199. $str = '';
  200. for ($i = 0; $i < strlen($string); $i++)
  201. {
  202. $str .= substr($string, $i, 1) ^ substr($hash, ($i % strlen($hash)), 1);
  203. }
  204. return $str;
  205. }
  206. // --------------------------------------------------------------------
  207. /**
  208. * Encrypt using Mcrypt
  209. *
  210. * @access public
  211. * @param string
  212. * @param string
  213. * @return string
  214. */
  215. function mcrypt_encode($data, $key)
  216. {
  217. $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
  218. $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
  219. return mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect);
  220. }
  221. // --------------------------------------------------------------------
  222. /**
  223. * Decrypt using Mcrypt
  224. *
  225. * @access public
  226. * @param string
  227. * @param string
  228. * @return string
  229. */
  230. function mcrypt_decode($data, $key)
  231. {
  232. $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
  233. $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
  234. return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");
  235. }
  236. // --------------------------------------------------------------------
  237. /**
  238. * Set the Mcrypt Cipher
  239. *
  240. * @access public
  241. * @param constant
  242. * @return string
  243. */
  244. function set_cipher($cipher)
  245. {
  246. $this->_mcrypt_cipher = $cipher;
  247. }
  248. // --------------------------------------------------------------------
  249. /**
  250. * Set the Mcrypt Mode
  251. *
  252. * @access public
  253. * @param constant
  254. * @return string
  255. */
  256. function set_mode($mode)
  257. {
  258. $this->_mcrypt_mode = $mode;
  259. }
  260. // --------------------------------------------------------------------
  261. /**
  262. * Get Mcrypt cipher Value
  263. *
  264. * @access private
  265. * @return string
  266. */
  267. function _get_cipher()
  268. {
  269. if ($this->_mcrypt_cipher == '')
  270. {
  271. $this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;
  272. }
  273. return $this->_mcrypt_cipher;
  274. }
  275. // --------------------------------------------------------------------
  276. /**
  277. * Get Mcrypt Mode Value
  278. *
  279. * @access private
  280. * @return string
  281. */
  282. function _get_mode()
  283. {
  284. if ($this->_mcrypt_mode == '')
  285. {
  286. $this->_mcrypt_mode = MCRYPT_MODE_ECB;
  287. }
  288. return $this->_mcrypt_mode;
  289. }
  290. // --------------------------------------------------------------------
  291. /**
  292. * Set the Hash type
  293. *
  294. * @access public
  295. * @param string
  296. * @return string
  297. */
  298. function set_hash($type = 'sha1')
  299. {
  300. $this->_hash_type = ($type != 'sha1' AND $type != 'md5') ? 'sha1' : $type;
  301. }
  302. // --------------------------------------------------------------------
  303. /**
  304. * Hash encode a string
  305. *
  306. * @access public
  307. * @param string
  308. * @return string
  309. */
  310. function hash($str)
  311. {
  312. return ($this->_hash_type == 'sha1') ? $this->sha1($str) : md5($str);
  313. }
  314. // --------------------------------------------------------------------
  315. /**
  316. * Generate an SHA1 Hash
  317. *
  318. * @access public
  319. * @param string
  320. * @return string
  321. */
  322. function sha1($str)
  323. {
  324. if ( ! function_exists('sha1'))
  325. {
  326. if ( ! function_exists('mhash'))
  327. {
  328. require_once(BASEPATH.'libraries/Sha1'.EXT);
  329. $SH = new CI_SHA;
  330. return $SH->generate($str);
  331. }
  332. else
  333. {
  334. return bin2hex(mhash(MHASH_SHA1, $str));
  335. }
  336. }
  337. else
  338. {
  339. return sha1($str);
  340. }
  341. }
  342. }
  343. // END CI_Encrypt class
  344. ?>