PageRenderTime 70ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/RNA/crypt.php

https://bitbucket.org/blipi/rna
PHP | 294 lines | 245 code | 8 blank | 41 comment | 2 complexity | 66a52a414177592c748f92f8f850d8fd MD5 | raw file
  1. <?php
  2. define("MODE_ECB",0);
  3. define("MODE_CBC",1);
  4. /**
  5. * An abstract layer class to encrypt data.
  6. *
  7. * This class is class is used to encrypt and decrypt data using different algorithms
  8. * and modes.
  9. *
  10. * @author Igor Ribeiro de Assis <igor21@terra.com.br>
  11. * @version 1.0-beta
  12. * @access public
  13. * @package Perfect Crypt
  14. */
  15. class pcrypt
  16. {
  17. /** Encryption Block Mode: ECB, CBC actually.
  18. *
  19. * @var int the mode used
  20. * @access private
  21. */
  22. var $blockmode = MODE_ECB;
  23. /** Key for Encryption
  24. *
  25. * @var string the key used in encryption and decryption
  26. * @access public
  27. */
  28. var $key = null;
  29. /** IV - Initialization Vector String
  30. *
  31. * @var string initialization vector for some modes (CBC)
  32. * @access public
  33. */
  34. var $iv = "z4c8e7gh";
  35. /** Methods */
  36. /** Constructor of the class.
  37. *
  38. * The constructor initialize some important vars and include the algorithm
  39. * file.
  40. *
  41. * @access public
  42. * @param int $blockmode the blockmode to use
  43. * @param string $cipher the algorithm used to crypt
  44. * @param string $key the ley used to crypt
  45. *
  46. * @return void
  47. */
  48. function pcrypt($blockmode = MODE_ECB, $cipher = 'BLOWFISH', $key = null, $array = false)
  49. {
  50. // Include cipher_class file
  51. $cipher = strtolower($cipher);
  52. if (!file_exists("./cipher/".$cipher.".php"))
  53. {
  54. $this->error("Unknown Cipher ".$cipher);
  55. }
  56. include_once "./cipher/".$cipher.".php";
  57. // Load cipher_class
  58. if (!class_exists("pcrypt_".$cipher))
  59. {
  60. $this->error("Class pcrypt_".$cipher." doesn't exists");
  61. }
  62. $class = "pcrypt_".$cipher;
  63. $this->cipher = new $class($key, $array);
  64. // Initialize Vars
  65. $this->blockmode = $blockmode;
  66. $this->key = $key;
  67. }
  68. /** Crypt data using the selected algorithm
  69. *
  70. * This method encrypt data using the selected algorithm and mode:
  71. * Algorithms: Blowfish
  72. * Modes: ECB, CBC
  73. * For a description about algorithms and modes see:
  74. * Applied Cryptography by Bruce Schneier
  75. *
  76. * @access public
  77. * @param string $plain the plain text to be encrypted
  78. * @return string $cipher the plain text encrypted
  79. */
  80. function encrypt($plain)
  81. {
  82. if (empty($plain))
  83. {
  84. $this->error("Empty Plain Text");
  85. }
  86. // Encrypt using the correct mode
  87. switch($this->blockmode) {
  88. case MODE_ECB:
  89. $cipher = $this->_ecb_encrypt($plain);
  90. break;
  91. case MODE_CBC:
  92. $cipher = $this->_cbc_encrypt($plain);
  93. break;
  94. default:
  95. $this->error("Invalid mode ".$this->blockmode);
  96. }
  97. return $cipher;
  98. }
  99. /** Decrypt using the selected algorithm
  100. *
  101. * This method decrypt data using the selected algorithm and mode.
  102. * TODO: Discover the algorithm and mode auto
  103. *
  104. * @access public
  105. * @param string $cipher the crypted data to be decrypted
  106. * @return string $plain the cipher text decrypted
  107. */
  108. function decrypt($cipher)
  109. {
  110. if (empty($cipher))
  111. {
  112. $this->error("Invalid Cipher Text");
  113. }
  114. // Decrypt with the correct mode
  115. switch($this->blockmode) {
  116. case MODE_ECB:
  117. $plain = $this->_ecb_decrypt($cipher);
  118. break;
  119. case MODE_CBC:
  120. $plain = $this->_cbc_decrypt($cipher);
  121. break;
  122. default:
  123. $this->error("Invalid mode ".$this->blockmode);
  124. }
  125. return $plain;
  126. }
  127. function getlen($len){
  128. if(method_exists($this->cipher, "_getlen"))
  129. return $this->cipher->_getlen($len);
  130. return -1;
  131. }
  132. /** Method to encrypt using ECB mode.
  133. *
  134. * In ECB mode the blocks are encrypted independently
  135. *
  136. * @access private
  137. * @param string $plain the plain text to be encrypted
  138. * @return string $cipher the plain text encrypted
  139. */
  140. function _ecb_encrypt($plain)
  141. {
  142. $blocksize = $this->cipher->blocksize;
  143. $plainsize = strlen($plain);
  144. $cipher = array();
  145. for($i = 0;$i < $plainsize;$i = $i + $blocksize)
  146. {
  147. $block = substr($plain,$i,$blocksize);
  148. while(strlen($block) < $blocksize)
  149. {
  150. // pad block with '\0'
  151. $block .= "\0";
  152. }
  153. $cipher = array_merge($cipher, $this->cipher->_encrypt($block));
  154. }
  155. return $cipher;
  156. }
  157. /** Method to decrypt using ECB mode.
  158. *
  159. * @access private
  160. * @param string $cipher the cipher text
  161. * @return string $plain the cipher text decrypted
  162. */
  163. function _ecb_decrypt($cipher)
  164. {
  165. $blocksize = $this->cipher->blocksize;
  166. $ciphersize = strlen($cipher);
  167. $plain = array();
  168. for($i = 0;$i < $ciphersize;$i = $i + $blocksize)
  169. {
  170. $block = substr($cipher,$i,$blocksize);
  171. $block = $this->cipher->_decrypt($block);
  172. // Remove padded chars
  173. for($n = 0; $n < $blocksize; $n++){
  174. if($block[$n] == "\0")
  175. $block[$n] = 0;
  176. }
  177. $plain = array_merge($plain, $block);
  178. }
  179. return $plain;
  180. }
  181. /** This method encrypt using CBC mode.
  182. *
  183. * In CBC mode each block is xored with the last. This function use $iv as
  184. * first block.
  185. *
  186. * @access private
  187. * @param string $plain the plain text to be decrypted
  188. * @return string $cipher the plain text encrypted
  189. */
  190. function _cbc_encrypt($plain)
  191. {
  192. $blocksize = $this->cipher->blocksize;
  193. $plainsize = strlen($plain);
  194. $cipher = '';
  195. $lcipher = $this->iv;
  196. // encrypt each block
  197. for($i = 0;$i < $plainsize;$i = $i + $blocksize)
  198. {
  199. $block = substr($plain,$i,$blocksize);
  200. if(strlen($block) < $blocksize)
  201. {
  202. // pad block with '\0'
  203. $block = str_pad($block,$blocksize,"\0",STR_PAD_LEFT);
  204. }
  205. // crypt the block xored with the last cipher block
  206. $lcipher = $this->cipher->_encrypt($block ^ $lcipher);
  207. $cipher .= $lcipher;
  208. }
  209. return $cipher;
  210. }
  211. /** This method decrypt using CBC.
  212. *
  213. * @access private
  214. * @param string $cipher the cipher text
  215. * @return string $plain the cipher text decrypted
  216. */
  217. function _cbc_decrypt($cipher)
  218. {
  219. // get the block size of the cipher
  220. $blocksize = $this->cipher->blocksize;
  221. $ciphersize = strlen($cipher);
  222. $plain = '';
  223. $lcipher = $this->iv;
  224. for($i = 0;$i < $ciphersize;$i = $i + $blocksize)
  225. {
  226. $block = substr($cipher,$i,$blocksize);
  227. // xor the block with the last cipher block
  228. $dblock = $lcipher ^ $this->cipher->_decrypt($block);
  229. $lcipher = $block;
  230. // Remove padded chars
  231. while(substr($dblock,0,1) == "\0")
  232. {
  233. $dblock = substr($dblock,1);
  234. }
  235. $plain .= $dblock;
  236. }
  237. return $plain;
  238. }
  239. /**
  240. * A simple function for error handling.
  241. *
  242. * TODO: Improve the error handling of the class
  243. *
  244. * @access private
  245. * @param string $message erro message
  246. * @return boolean true
  247. */
  248. function error($message)
  249. {
  250. echo "Error: ".$message."<br>";
  251. return 1;
  252. }
  253. }
  254. ?>