PageRenderTime 88ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Joomla/Crypt/Cipher/Simple.php

https://github.com/dianaprajescu/joomla-framework
PHP | 281 lines | 152 code | 34 blank | 95 comment | 13 complexity | 0f32eed3a33eda50dac5581fcf8f84e2 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Part of the Joomla Framework Crypt Package
  4. *
  5. * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
  6. * @license GNU General Public License version 2 or later; see LICENSE
  7. */
  8. namespace Joomla\Crypt;
  9. /**
  10. * JCrypt cipher for Simple encryption, decryption and key generation.
  11. *
  12. * @since 1.0
  13. */
  14. class Cipher_Simple implements CipherInterface
  15. {
  16. /**
  17. * Method to decrypt a data string.
  18. *
  19. * @param string $data The encrypted string to decrypt.
  20. * @param Key $key The key[/pair] object to use for decryption.
  21. *
  22. * @return string The decrypted data string.
  23. *
  24. * @since 1.0
  25. * @throws \InvalidArgumentException
  26. */
  27. public function decrypt($data, Key $key)
  28. {
  29. // Validate key.
  30. if ($key->type != 'simple')
  31. {
  32. throw new \InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected simple.');
  33. }
  34. $decrypted = '';
  35. $tmp = $key->public;
  36. // Convert the HEX input into an array of integers and get the number of characters.
  37. $chars = $this->_hexToIntArray($data);
  38. $charCount = count($chars);
  39. // Repeat the key as many times as necessary to ensure that the key is at least as long as the input.
  40. for ($i = 0; $i < $charCount; $i = strlen($tmp))
  41. {
  42. $tmp = $tmp . $tmp;
  43. }
  44. // Get the XOR values between the ASCII values of the input and key characters for all input offsets.
  45. for ($i = 0; $i < $charCount; $i++)
  46. {
  47. $decrypted .= chr($chars[$i] ^ ord($tmp[$i]));
  48. }
  49. return $decrypted;
  50. }
  51. /**
  52. * Method to encrypt a data string.
  53. *
  54. * @param string $data The data string to encrypt.
  55. * @param Key $key The key[/pair] object to use for encryption.
  56. *
  57. * @return string The encrypted data string.
  58. *
  59. * @since 1.0
  60. * @throws \InvalidArgumentException
  61. */
  62. public function encrypt($data, Key $key)
  63. {
  64. // Validate key.
  65. if ($key->type != 'simple')
  66. {
  67. throw new \InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected simple.');
  68. }
  69. $encrypted = '';
  70. $tmp = $key->private;
  71. // Split up the input into a character array and get the number of characters.
  72. $chars = preg_split('//', $data, -1, PREG_SPLIT_NO_EMPTY);
  73. $charCount = count($chars);
  74. // Repeat the key as many times as necessary to ensure that the key is at least as long as the input.
  75. for ($i = 0; $i < $charCount; $i = strlen($tmp))
  76. {
  77. $tmp = $tmp . $tmp;
  78. }
  79. // Get the XOR values between the ASCII values of the input and key characters for all input offsets.
  80. for ($i = 0; $i < $charCount; $i++)
  81. {
  82. $encrypted .= $this->_intToHex(ord($tmp[$i]) ^ ord($chars[$i]));
  83. }
  84. return $encrypted;
  85. }
  86. /**
  87. * Method to generate a new encryption key[/pair] object.
  88. *
  89. * @param array $options Key generation options.
  90. *
  91. * @return Key
  92. *
  93. * @since 1.0
  94. */
  95. public function generateKey(array $options = array())
  96. {
  97. // Create the new encryption key[/pair] object.
  98. $key = new Key('simple');
  99. // Just a random key of a given length.
  100. $key->private = $this->_getRandomKey();
  101. $key->public = $key->private;
  102. return $key;
  103. }
  104. /**
  105. * Method to generate a random key of a given length.
  106. *
  107. * @param integer $length The length of the key to generate.
  108. *
  109. * @return string
  110. *
  111. * @since 1.0
  112. */
  113. private function _getRandomKey($length = 256)
  114. {
  115. $key = '';
  116. $salt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  117. $saltLength = strlen($salt);
  118. // Build the random key.
  119. for ($i = 0; $i < $length; $i++)
  120. {
  121. $key .= $salt[mt_rand(0, $saltLength - 1)];
  122. }
  123. return $key;
  124. }
  125. /**
  126. * Convert hex to an integer
  127. *
  128. * @param string $s The hex string to convert.
  129. * @param integer $i The offset?
  130. *
  131. * @return integer
  132. *
  133. * @since 1.0
  134. */
  135. private function _hexToInt($s, $i)
  136. {
  137. $j = (int) $i * 2;
  138. $k = 0;
  139. $s1 = (string) $s;
  140. // Get the character at position $j.
  141. $c = substr($s1, $j, 1);
  142. // Get the character at position $j + 1.
  143. $c1 = substr($s1, $j + 1, 1);
  144. switch ($c)
  145. {
  146. case 'A':
  147. $k += 160;
  148. break;
  149. case 'B':
  150. $k += 176;
  151. break;
  152. case 'C':
  153. $k += 192;
  154. break;
  155. case 'D':
  156. $k += 208;
  157. break;
  158. case 'E':
  159. $k += 224;
  160. break;
  161. case 'F':
  162. $k += 240;
  163. break;
  164. case ' ':
  165. $k += 0;
  166. break;
  167. default:
  168. $k = $k + (16 * (int) $c);
  169. break;
  170. }
  171. switch ($c1)
  172. {
  173. case 'A':
  174. $k += 10;
  175. break;
  176. case 'B':
  177. $k += 11;
  178. break;
  179. case 'C':
  180. $k += 12;
  181. break;
  182. case 'D':
  183. $k += 13;
  184. break;
  185. case 'E':
  186. $k += 14;
  187. break;
  188. case 'F':
  189. $k += 15;
  190. break;
  191. case ' ':
  192. $k += 0;
  193. break;
  194. default:
  195. $k += (int) $c1;
  196. break;
  197. }
  198. return $k;
  199. }
  200. /**
  201. * Convert hex to an array of integers
  202. *
  203. * @param string $hex The hex string to convert to an integer array.
  204. *
  205. * @return array An array of integers.
  206. *
  207. * @since 1.0
  208. */
  209. private function _hexToIntArray($hex)
  210. {
  211. $array = array();
  212. $j = (int) strlen($hex) / 2;
  213. for ($i = 0; $i < $j; $i++)
  214. {
  215. $array[$i] = (int) $this->_hexToInt($hex, $i);
  216. }
  217. return $array;
  218. }
  219. /**
  220. * Convert an integer to a hexadecimal string.
  221. *
  222. * @param integer $i An integer value to convert to a hex string.
  223. *
  224. * @return string
  225. *
  226. * @since 1.0
  227. */
  228. private function _intToHex($i)
  229. {
  230. // Sanitize the input.
  231. $i = (int) $i;
  232. // Get the first character of the hexadecimal string if there is one.
  233. $j = (int) ($i / 16);
  234. if ($j === 0)
  235. {
  236. $s = ' ';
  237. }
  238. else
  239. {
  240. $s = strtoupper(dechex($j));
  241. }
  242. // Get the second character of the hexadecimal string.
  243. $k = $i - $j * 16;
  244. $s = $s . strtoupper(dechex($k));
  245. return $s;
  246. }
  247. }