1 <?php
2 3 4 5 6 7
8
9 defined('FOF_INCLUDED') or die;
10
11 12 13 14 15 16 17
18 class FOFEncryptAes
19 {
20 21 22 23 24
25 protected $key = '';
26
27 28 29 30 31
32 protected $adapter;
33
34 35 36 37 38 39 40 41 42 43 44 45
46 public function __construct($key, $strength = 128, $mode = 'cbc', FOFUtilsPhpfunc $phpfunc = null, $priority = 'openssl')
47 {
48 if ($priority == 'openssl')
49 {
50 $this->adapter = new FOFEncryptAesOpenssl();
51
52 if (!$this->adapter->isSupported($phpfunc))
53 {
54 $this->adapter = new FOFEncryptAesMcrypt();
55 }
56 }
57 else
58 {
59 $this->adapter = new FOFEncryptAesMcrypt();
60
61 if (!$this->adapter->isSupported($phpfunc))
62 {
63 $this->adapter = new FOFEncryptAesOpenssl();
64 }
65 }
66
67 $this->adapter->setEncryptionMode($mode, $strength);
68 $this->setPassword($key, true);
69 }
70
71 72 73 74 75 76 77 78
79 public function setPassword($password, $legacyMode = false)
80 {
81 $this->key = $password;
82
83 $passLength = strlen($password);
84
85 if (function_exists('mb_strlen'))
86 {
87 $passLength = mb_strlen($password, 'ASCII');
88 }
89
90
91 if ($legacyMode && ($passLength != 32))
92 {
93
94 $this->key = hash('sha256', $password, true);
95
96 $this->key = $this->adapter->resizeKey($this->key, $this->adapter->getBlockSize());
97 }
98 }
99
100 101 102 103 104 105 106 107 108 109
110 public function encryptString($stringToEncrypt, $base64encoded = true)
111 {
112 $blockSize = $this->adapter->getBlockSize();
113 $randVal = new FOFEncryptRandval();
114 $iv = $randVal->generate($blockSize);
115
116 $key = $this->getExpandedKey($blockSize, $iv);
117 $cipherText = $this->adapter->encrypt($stringToEncrypt, $key, $iv);
118
119
120 if ($base64encoded)
121 {
122 $cipherText = base64_encode($cipherText);
123 }
124
125
126 return $cipherText;
127 }
128
129 130 131 132 133 134 135 136 137
138 public function decryptString($stringToDecrypt, $base64encoded = true)
139 {
140 if ($base64encoded)
141 {
142 $stringToDecrypt = base64_decode($stringToDecrypt);
143 }
144
145
146 $iv_size = $this->adapter->getBlockSize();
147 $iv = substr($stringToDecrypt, 0, $iv_size);
148 $key = $this->getExpandedKey($iv_size, $iv);
149
150
151 $plainText = $this->adapter->decrypt($stringToDecrypt, $key);
152
153 return $plainText;
154 }
155
156 157 158 159 160 161 162
163 public static function isSupported(FOFUtilsPhpfunc $phpfunc = null)
164 {
165 if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc))
166 {
167 $phpfunc = new FOFUtilsPhpfunc();
168 }
169
170 $adapter = new FOFEncryptAesMcrypt();
171
172 if (!$adapter->isSupported($phpfunc))
173 {
174 $adapter = new FOFEncryptAesOpenssl();
175 }
176
177 if (!$adapter->isSupported($phpfunc))
178 {
179 return false;
180 }
181
182 if (!$phpfunc->function_exists('base64_encode'))
183 {
184 return false;
185 }
186
187 if (!$phpfunc->function_exists('base64_decode'))
188 {
189 return false;
190 }
191
192 if (!$phpfunc->function_exists('hash_algos'))
193 {
194 return false;
195 }
196
197 $algorightms = $phpfunc->hash_algos();
198
199 if (!in_array('sha256', $algorightms))
200 {
201 return false;
202 }
203
204 return true;
205 }
206
207 208 209 210 211 212
213 public function getExpandedKey($blockSize, $iv)
214 {
215 $key = $this->key;
216 $passLength = strlen($key);
217
218 if (function_exists('mb_strlen'))
219 {
220 $passLength = mb_strlen($key, 'ASCII');
221 }
222
223 if ($passLength != $blockSize)
224 {
225 $iterations = 1000;
226 $salt = $this->adapter->resizeKey($iv, 16);
227 $key = hash_pbkdf2('sha256', $this->key, $salt, $iterations, $blockSize, true);
228 }
229
230 return $key;
231 }
232 }
233
234 if (!function_exists('hash_pbkdf2'))
235 {
236 function hash_pbkdf2($algo, $password, $salt, $count, $length = 0, $raw_output = false)
237 {
238 if (!in_array(strtolower($algo), hash_algos()))
239 {
240 trigger_error(__FUNCTION__ . '(): Unknown hashing algorithm: ' . $algo, E_USER_WARNING);
241 }
242
243 if (!is_numeric($count))
244 {
245 trigger_error(__FUNCTION__ . '(): expects parameter 4 to be long, ' . gettype($count) . ' given', E_USER_WARNING);
246 }
247
248 if (!is_numeric($length))
249 {
250 trigger_error(__FUNCTION__ . '(): expects parameter 5 to be long, ' . gettype($length) . ' given', E_USER_WARNING);
251 }
252
253 if ($count <= 0)
254 {
255 trigger_error(__FUNCTION__ . '(): Iterations must be a positive integer: ' . $count, E_USER_WARNING);
256 }
257
258 if ($length < 0)
259 {
260 trigger_error(__FUNCTION__ . '(): Length must be greater than or equal to 0: ' . $length, E_USER_WARNING);
261 }
262
263 $output = '';
264 $block_count = $length ? ceil($length / strlen(hash($algo, '', $raw_output))) : 1;
265
266 for ($i = 1; $i <= $block_count; $i++)
267 {
268 $last = $xorsum = hash_hmac($algo, $salt . pack('N', $i), $password, true);
269
270 for ($j = 1; $j < $count; $j++)
271 {
272 $xorsum ^= ($last = hash_hmac($algo, $last, $password, true));
273 }
274
275 $output .= $xorsum;
276 }
277
278 if (!$raw_output)
279 {
280 $output = bin2hex($output);
281 }
282
283 return $length ? substr($output, 0, $length) : $output;
284 }
285 }
286