simplecrypt.class.inc.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. // Copyright (C) 2010-2012 Combodo SARL
  3. //
  4. // This file is part of iTop.
  5. //
  6. // iTop is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // iTop is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with iTop. If not, see <http://www.gnu.org/licenses/>
  18. /**
  19. * SimpleCrypt Class - crypto helpers
  20. * Simple encryption of strings, uses mcrypt or degrades to a pure PHP
  21. * implementation when mcrypt is not present.
  22. * Based on Miguel Ros' work found at:
  23. * http://rossoft.wordpress.com/2006/05/22/simple-encryption-class/
  24. *
  25. * Usage:
  26. * $oSimpleCrypt = new SimpleCrypt();
  27. * $encrypted = $oSimpleCrypt->encrypt('a_key','the_text');
  28. * $sClearText = $oSimpleCrypt->decrypt('a_key',$encrypted);
  29. *
  30. * The result is $plain equals to 'the_text'
  31. *
  32. * You can use a different engine if you don't have Mcrypt:
  33. * $oSimpleCrypt = new SimpleCrypt('Simple');
  34. *
  35. * A string encrypted with one engine can't be decrypted with
  36. * a different one even if the key is the same.
  37. *
  38. * @author Miguel Ros <rossoft@gmail.com>
  39. * @copyright Copyright (C) 2010-2012 Combodo SARL
  40. * @license http://opensource.org/licenses/AGPL-3.0
  41. */
  42. class SimpleCrypt
  43. {
  44. /**
  45. * Constructor
  46. * @param string $sEngineName Engine for encryption. Values: Simple, Mcrypt
  47. */
  48. function __construct($sEngineName = 'Mcrypt')
  49. {
  50. if (($sEngineName == 'Mcrypt') && (!function_exists('mcrypt_module_open')))
  51. {
  52. // Defaults to Simple encryption if the mcrypt module is not present
  53. $sEngineName = 'Simple';
  54. }
  55. $sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine';
  56. $this->oEngine = new $sEngineName;
  57. }
  58. /**
  59. * Encrypts the string with the given key
  60. * @param string $key
  61. * @param string $sString Plaintext string
  62. * @return string Ciphered string
  63. */
  64. function Encrypt($key, $sString)
  65. {
  66. return $this->oEngine->Encrypt($key,$sString);
  67. }
  68. /**
  69. * Decrypts the string by the given key
  70. * @param string $key
  71. * @param string $string Ciphered string
  72. * @return string Plaintext string
  73. */
  74. function Decrypt($key, $string)
  75. {
  76. return $this->oEngine->Decrypt($key,$string);
  77. }
  78. /**
  79. * Returns a random "salt" value, to be used when "hashing" a password
  80. * using a one-way encryption algorithm, to prevent an attack using a "rainbow table"
  81. * Tryes to use the best available random number generator
  82. * @return string The generated random "salt"
  83. */
  84. static function GetNewSalt()
  85. {
  86. // Copied from http://www.php.net/manual/en/function.mt-rand.php#83655
  87. // get 128 pseudorandom bits in a string of 16 bytes
  88. $sRandomBits = null;
  89. // Unix/Linux platform?
  90. $fp = @fopen('/dev/urandom','rb');
  91. if ($fp !== FALSE)
  92. {
  93. //echo "Random bits pulled from /dev/urandom<br/>\n";
  94. $sRandomBits .= @fread($fp,16);
  95. @fclose($fp);
  96. }
  97. else
  98. {
  99. // MS-Windows platform?
  100. if (@class_exists('COM'))
  101. {
  102. // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
  103. try
  104. {
  105. $CAPI_Util = new COM('CAPICOM.Utilities.1');
  106. $sBase64RandomBits = ''.$CAPI_Util->GetRandom(16,0);
  107. // if we ask for binary data PHP munges it, so we
  108. // request base64 return value. We squeeze out the
  109. // redundancy and useless ==CRLF by hashing...
  110. if ($sBase64RandomBits)
  111. {
  112. //echo "Random bits got from CAPICOM.Utilities.1<br/>\n";
  113. $sRandomBits = md5($sBase64RandomBits, TRUE);
  114. }
  115. }
  116. catch (Exception $ex)
  117. {
  118. // echo 'Exception: ' . $ex->getMessage();
  119. }
  120. }
  121. }
  122. if ($sRandomBits == null)
  123. {
  124. // No "strong" random generator available, use PHP's built-in mechanism
  125. //echo "Random bits generated from mt_rand<br/>\n";
  126. mt_srand(crc32(microtime()));
  127. $sRandomBits = '';
  128. for($i = 0; $i < 4; $i++)
  129. {
  130. $sRandomBits .= sprintf('%04x', mt_rand(0, 65535));
  131. }
  132. }
  133. return $sRandomBits;
  134. }
  135. }
  136. /**
  137. * Interface for encryption engines
  138. */
  139. interface CryptEngine
  140. {
  141. function Encrypt($key, $sString);
  142. function Decrypt($key, $encrypted_data);
  143. }
  144. /**
  145. * Simple Engine doesn't need any PHP extension.
  146. * Every encryption of the same string with the same key
  147. * will return the same encrypted string
  148. */
  149. class SimpleCryptSimpleEngine implements CryptEngine
  150. {
  151. public function Encrypt($key, $sString)
  152. {
  153. $result = '';
  154. for($i=1; $i<=strlen($sString); $i++)
  155. {
  156. $char = substr($sString, $i-1, 1);
  157. $keychar = substr($key, ($i % strlen($key))-1, 1);
  158. $char = chr(ord($char)+ord($keychar));
  159. $result.=$char;
  160. }
  161. return $result;
  162. }
  163. public function Decrypt($key, $encrypted_data)
  164. {
  165. $result = '';
  166. for($i=1; $i<=strlen($encrypted_data); $i++)
  167. {
  168. $char = substr($encrypted_data, $i-1, 1);
  169. $keychar = substr($key, ($i % strlen($key))-1, 1);
  170. $char = chr(ord($char)-ord($keychar));
  171. $result.=$char;
  172. }
  173. return $result;
  174. }
  175. }
  176. /**
  177. * McryptEngine requires Mcrypt extension
  178. * Every encryption of the same string with the same key
  179. * will return a different encrypted string.
  180. */
  181. class SimpleCryptMcryptEngine implements CryptEngine
  182. {
  183. var $alg = MCRYPT_BLOWFISH;
  184. var $td = null;
  185. public function __construct()
  186. {
  187. $this->td = mcrypt_module_open($this->alg,'','cbc','');
  188. }
  189. public function Encrypt($key, $sString)
  190. {
  191. $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND); // MCRYPT_RAND is the only choice on Windows prior to PHP 5.3
  192. mcrypt_generic_init($this->td, $key, $iv);
  193. if (empty($sString))
  194. {
  195. $sString = str_repeat("\0", 8);
  196. }
  197. $encrypted_data = mcrypt_generic($this->td, $sString);
  198. mcrypt_generic_deinit($this->td);
  199. return $iv.$encrypted_data;
  200. }
  201. public function Decrypt($key, $encrypted_data)
  202. {
  203. $iv = substr($encrypted_data, 0, mcrypt_enc_get_iv_size($this->td));
  204. $string = substr($encrypted_data, mcrypt_enc_get_iv_size($this->td));
  205. mcrypt_generic_init($this->td, $key, $iv);
  206. $decrypted_data = rtrim(mdecrypt_generic($this->td, $string), "\0");
  207. mcrypt_generic_deinit($this->td);
  208. return $decrypted_data;
  209. }
  210. public function __destruct()
  211. {
  212. mcrypt_module_close($this->td);
  213. }
  214. }
  215. ?>