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