PageRenderTime 26ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/fuel/core/classes/crypt.php

https://github.com/akutaktau/feedmalaya
PHP | 331 lines | 167 code | 45 blank | 119 comment | 22 complexity | 4997983d576a7dab5a14575a600cbcb9 MD5 | raw file
  1. <?php
  2. /**
  3. * Fuel
  4. *
  5. * Fuel is a fast, lightweight, community driven PHP5 framework.
  6. *
  7. * @package Fuel
  8. * @version 1.0
  9. * @author Fuel Development Team
  10. * @license MIT License
  11. * @copyright 2010 - 2011 Fuel Development Team
  12. * @link http://fuelphp.com
  13. */
  14. namespace Fuel\Core;
  15. /**
  16. * Crypt Class
  17. *
  18. * @package Fuel
  19. * @category Core
  20. * @author Harro "WanWizard" Verton
  21. * @link http://fuelphp.com/docs/classes/crypt.html
  22. */
  23. class Crypt {
  24. /**
  25. * @var boolean idicator for the usage of mcrypt
  26. */
  27. public static $use_mcrypt = true;
  28. /**
  29. * @var string Magic salt to use as encryption key
  30. */
  31. public static $salt = 'sup3rs3Cr3tk3y564';
  32. /**
  33. * @var boolean idicator for the availability of mcrypt
  34. */
  35. protected static $have_mcrypt = false;
  36. /**
  37. * @var int default mcrypt cipher to use
  38. */
  39. protected static $mcrypt_cipher = 'rijndael-256';
  40. /**
  41. * @var int default mcrypt mode to use
  42. */
  43. protected static $mcrypt_mode = 'cbc';
  44. // --------------------------------------------------------------------
  45. /*
  46. * initialisation and auto configuration
  47. */
  48. public static function _init()
  49. {
  50. // check we we have the mcrypt library available
  51. static::$have_mcrypt = function_exists('mcrypt_encrypt');
  52. // load the config
  53. \Config::load('crypt', true);
  54. $config = \Config::get('crypt', array ());
  55. // update the defaults with the configed values
  56. foreach($config as $key => $value)
  57. {
  58. isset(static::${$key}) && static::${$key} = $value;
  59. }
  60. }
  61. // --------------------------------------------------------------------
  62. /*
  63. * set a configuration value
  64. *
  65. * @param string name of the configuration key
  66. * @param string value to be set
  67. * @access public
  68. * @return void
  69. */
  70. public static function set($name = false, $value = null)
  71. {
  72. $name && isset(static::${$name}) && static::${$name} = $value;
  73. }
  74. // --------------------------------------------------------------------
  75. /*
  76. * get a configuration value
  77. *
  78. * @param string name of the configuration key
  79. * @access public
  80. * @return string the configuration key value, or false if the key is invalid
  81. */
  82. public static function get($name = false)
  83. {
  84. return $name && isset(static::${$name}) ? static::${$name} : false;
  85. }
  86. // --------------------------------------------------------------------
  87. /*
  88. * encrypt a string value, optionally with a custom salt
  89. *
  90. * @param string value to encrypt
  91. * @param string optional salt to be used for this encryption
  92. * @access public
  93. * @return string encrypted value
  94. */
  95. public static function encode($value, $salt = false)
  96. {
  97. // if no salt is given, use the default salt
  98. if ($salt === false)
  99. {
  100. $salt = static::$salt;
  101. }
  102. // check if we have mcrypt available, and we want to use it
  103. if (static::$have_mcrypt && static::$use_mcrypt)
  104. {
  105. // encrypt using mcrypt
  106. $iv_size = mcrypt_get_iv_size(static::$mcrypt_cipher, static::$mcrypt_mode);
  107. $iv_vector = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  108. $value = '1:'.static::_add_cipher_noise($iv_vector.mcrypt_encrypt(static::$mcrypt_cipher, $salt, $value, static::$mcrypt_mode, $iv_vector), $salt);
  109. }
  110. else
  111. {
  112. $keys = static::_crypt_key($salt);
  113. for($i = 0; $i < strlen($value); $i++){
  114. $id = $i % (count($keys)-3);
  115. $ord = ord($value{$i});
  116. $ord = $ord OR ord($keys[$id]);
  117. $id++;
  118. $ord = $ord AND ord($keys[$id]);
  119. $id++;
  120. $ord = $ord XOR ord($keys[$id]);
  121. $id++;
  122. $ord = $ord + ord($keys[$id]);
  123. $value{$i} = chr($ord);
  124. }
  125. $value = '0:'.$value;
  126. }
  127. // make the encoding URL save
  128. return strtr(
  129. base64_encode($value),
  130. array(
  131. '+' => '.',
  132. '=' => '-',
  133. '/' => '~'
  134. )
  135. );
  136. }
  137. // --------------------------------------------------------------------
  138. /*
  139. * decrypt a string value, optionally with a custom salt
  140. *
  141. * the method automatically detects if mcrypt was used on encryption
  142. *
  143. * @param string value to decrypt
  144. * @param string optional salt to be used for this encryption
  145. * @access public
  146. * @return string encrypted value
  147. */
  148. public static function decode($value, $salt = false)
  149. {
  150. // if no salt is given, use the default salt
  151. if ($salt === false)
  152. {
  153. $salt = static::$salt;
  154. }
  155. // decode the value passed
  156. $value = base64_decode(strtr(
  157. $value,
  158. array(
  159. '.' => '+',
  160. '-' => '=',
  161. '~' => '/'
  162. )
  163. ));
  164. // check if we have mcrypt available, and the value was encrypted by mcrypt
  165. if (static::$have_mcrypt && substr($value,0,2) == '1:')
  166. {
  167. // decrypt using mcrypt
  168. $value = static::_remove_cipher_noise(substr($value,2), $salt);
  169. $iv_size = mcrypt_get_iv_size(static::$mcrypt_cipher, static::$mcrypt_mode);
  170. if ($iv_size > strlen($value))
  171. {
  172. return false;
  173. }
  174. $iv_vector = substr($value, 0, $iv_size);
  175. $value = substr($value, $iv_size);
  176. $value = rtrim(mcrypt_decrypt(static::$mcrypt_cipher, $salt, $value, static::$mcrypt_mode, $iv_vector), "\0");
  177. }
  178. else
  179. {
  180. // was the value encrypted using mcrypt
  181. if (substr($value,0,2) == '1:')
  182. {
  183. // houston, we have a problem!
  184. throw new \Fuel_Exception('Encrypted string was encrypted using the PHP mcrypt library, which is not loaded on this system.');
  185. }
  186. $value = substr($value,2);
  187. $keys = static::_crypt_key($salt);
  188. for($i = 0; $i < strlen($value); $i++){
  189. $id = $i % (count($keys)-3);
  190. $ord = ord($value{$i});
  191. $ord = $ord XOR ord($keys[$id]);
  192. $id++;
  193. $ord = $ord AND ord($keys[$id]);
  194. $id++;
  195. $ord = $ord OR ord($keys[$id]);
  196. $id++;
  197. $ord = $ord - ord($keys[$id]);
  198. $value{$i} = chr($ord);
  199. }
  200. }
  201. return $value;
  202. }
  203. // --------------------------------------------------------------------
  204. /**
  205. * Adds permuted noise to the IV + encrypted data to protect
  206. * against Man-in-the-middle attacks on CBC mode ciphers
  207. * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV
  208. *
  209. * @param string
  210. * @param string
  211. * @access private
  212. * @return string
  213. */
  214. protected static function _add_cipher_noise($value, $salt)
  215. {
  216. $keyhash = sha1($salt);
  217. $keylen = strlen($keyhash);
  218. $str = '';
  219. for ($i = 0, $j = 0, $len = strlen($value); $i < $len; ++$i, ++$j)
  220. {
  221. if ($j >= $keylen)
  222. {
  223. $j = 0;
  224. }
  225. $str .= chr((ord($value[$i]) + ord($keyhash[$j])) % 256);
  226. }
  227. return $str;
  228. }
  229. // --------------------------------------------------------------------
  230. /**
  231. * Removes permuted noise from the IV + encrypted data, reversing
  232. * _add_cipher_noise()
  233. *
  234. * @param string
  235. * @param string
  236. * @access private
  237. * @return string
  238. */
  239. protected static function _remove_cipher_noise($value, $salt)
  240. {
  241. $keyhash = sha1($salt);
  242. $keylen = strlen($keyhash);
  243. $str = '';
  244. for ($i = 0, $j = 0, $len = strlen($value); $i < $len; ++$i, ++$j)
  245. {
  246. if ($j >= $keylen)
  247. {
  248. $j = 0;
  249. }
  250. $temp = ord($value[$i]) - ord($keyhash[$j]);
  251. if ($temp < 0)
  252. {
  253. $temp = $temp + 256;
  254. }
  255. $str .= chr($temp);
  256. }
  257. return $str;
  258. }
  259. // --------------------------------------------------------------------
  260. /**
  261. * generate a crypt key for non-mcrypt encryption
  262. *
  263. * @param string salt
  264. * @access private
  265. * @return array keys used for the encryption algorithm
  266. */
  267. protected static function _crypt_key($salt)
  268. {
  269. $keys = array();
  270. $c_key = base64_encode(sha1(md5($salt)));
  271. $c_key = substr($c_key, 0, round(ord($salt{0})/5));
  272. $c2_key = base64_encode(md5(sha1($salt)));
  273. $last = strlen($salt) - 1;
  274. $c2_key = substr($c2_key, 1, round(ord($salt{$last})/7));
  275. $c3_key = base64_encode(sha1(md5($c_key).md5($c2_key)));
  276. $mid = round($last/2);
  277. $c3_key = substr($c3_key, 1, round(ord($salt{$mid})/9));
  278. $c_key = $c_key.$c2_key.$c3_key;
  279. $c_key = base64_encode($c_key);
  280. for($i = 0; $i < strlen($c_key); $i++){
  281. $keys[] = $c_key[$i];
  282. }
  283. return $keys;
  284. }
  285. }
  286. /* End of file encrypt.php */