/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk
20.1.1 by galaxyAbstractor
* Added an simple admin panel to the codeviewer-cmssy stuff
1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP 5.1.6 or newer
6
 *
7
 * @package		CodeIgniter
8
 * @author		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
10
 * @license		http://codeigniter.com/user_guide/license.html
11
 * @link		http://codeigniter.com
12
 * @since		Version 1.0
13
 * @filesource
14
 */
15
16
// ------------------------------------------------------------------------
17
18
/**
19
 * CodeIgniter Encryption Class
20
 *
21
 * Provides two-way keyed encoding using XOR Hashing and Mcrypt
22
 *
23
 * @package		CodeIgniter
24
 * @subpackage	Libraries
25
 * @category	Libraries
26
 * @author		ExpressionEngine Dev Team
27
 * @link		http://codeigniter.com/user_guide/libraries/encryption.html
28
 */
29
class CI_Encrypt {
30
31
	var $CI;
32
	var $encryption_key	= '';
33
	var $_hash_type	= 'sha1';
34
	var $_mcrypt_exists = FALSE;
35
	var $_mcrypt_cipher;
36
	var $_mcrypt_mode;
37
38
	/**
39
	 * Constructor
40
	 *
41
	 * Simply determines whether the mcrypt library exists.
42
	 *
43
	 */
44
	public function __construct()
45
	{
46
		$this->CI =& get_instance();
47
		$this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;
48
		log_message('debug', "Encrypt Class Initialized");
49
	}
50
51
	// --------------------------------------------------------------------
52
53
	/**
54
	 * Fetch the encryption key
55
	 *
56
	 * Returns it as MD5 in order to have an exact-length 128 bit key.
57
	 * Mcrypt is sensitive to keys that are not the correct length
58
	 *
59
	 * @access	public
60
	 * @param	string
61
	 * @return	string
62
	 */
63
	function get_key($key = '')
64
	{
65
		if ($key == '')
66
		{
67
			if ($this->encryption_key != '')
68
			{
69
				return $this->encryption_key;
70
			}
71
72
			$CI =& get_instance();
73
			$key = $CI->config->item('encryption_key');
74
75
			if ($key == FALSE)
76
			{
77
				show_error('In order to use the encryption class requires that you set an encryption key in your config file.');
78
			}
79
		}
80
81
		return md5($key);
82
	}
83
84
	// --------------------------------------------------------------------
85
86
	/**
87
	 * Set the encryption key
88
	 *
89
	 * @access	public
90
	 * @param	string
91
	 * @return	void
92
	 */
93
	function set_key($key = '')
94
	{
95
		$this->encryption_key = $key;
96
	}
97
98
	// --------------------------------------------------------------------
99
100
	/**
101
	 * Encode
102
	 *
103
	 * Encodes the message string using bitwise XOR encoding.
104
	 * The key is combined with a random hash, and then it
105
	 * too gets converted using XOR. The whole thing is then run
106
	 * through mcrypt (if supported) using the randomized key.
107
	 * The end result is a double-encrypted message string
108
	 * that is randomized with each call to this function,
109
	 * even if the supplied message and key are the same.
110
	 *
111
	 * @access	public
112
	 * @param	string	the string to encode
113
	 * @param	string	the key
114
	 * @return	string
115
	 */
116
	function encode($string, $key = '')
117
	{
118
		$key = $this->get_key($key);
119
120
		if ($this->_mcrypt_exists === TRUE)
121
		{
122
			$enc = $this->mcrypt_encode($string, $key);
123
		}
124
		else
125
		{
126
			$enc = $this->_xor_encode($string, $key);
127
		}
128
129
		return base64_encode($enc);
130
	}
131
132
	// --------------------------------------------------------------------
133
134
	/**
135
	 * Decode
136
	 *
137
	 * Reverses the above process
138
	 *
139
	 * @access	public
140
	 * @param	string
141
	 * @param	string
142
	 * @return	string
143
	 */
144
	function decode($string, $key = '')
145
	{
146
		$key = $this->get_key($key);
147
148
		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
149
		{
150
			return FALSE;
151
		}
152
153
		$dec = base64_decode($string);
154
155
		if ($this->_mcrypt_exists === TRUE)
156
		{
157
			if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)
158
			{
159
				return FALSE;
160
			}
161
		}
162
		else
163
		{
164
			$dec = $this->_xor_decode($dec, $key);
165
		}
166
167
		return $dec;
168
	}
169
170
	// --------------------------------------------------------------------
171
172
	/**
173
	 * Encode from Legacy
174
	 *
175
	 * Takes an encoded string from the original Encryption class algorithms and
176
	 * returns a newly encoded string using the improved method added in 2.0.0
177
	 * This allows for backwards compatibility and a method to transition to the
178
	 * new encryption algorithms.
179
	 *
180
	 * For more details, see http://codeigniter.com/user_guide/installation/upgrade_200.html#encryption
181
	 *
182
	 * @access	public
183
	 * @param	string
184
	 * @param	int		(mcrypt mode constant)
185
	 * @param	string
186
	 * @return	string
187
	 */
188
	function encode_from_legacy($string, $legacy_mode = MCRYPT_MODE_ECB, $key = '')
189
	{
190
		if ($this->_mcrypt_exists === FALSE)
191
		{
192
			log_message('error', 'Encoding from legacy is available only when Mcrypt is in use.');
193
			return FALSE;
194
		}
195
196
		// decode it first
197
		// set mode temporarily to what it was when string was encoded with the legacy
198
		// algorithm - typically MCRYPT_MODE_ECB
199
		$current_mode = $this->_get_mode();
200
		$this->set_mode($legacy_mode);
201
202
		$key = $this->get_key($key);
203
204
		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
205
		{
206
			return FALSE;
207
		}
208
209
		$dec = base64_decode($string);
210
211
		if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)
212
		{
213
			return FALSE;
214
		}
215
216
		$dec = $this->_xor_decode($dec, $key);
217
218
		// set the mcrypt mode back to what it should be, typically MCRYPT_MODE_CBC
219
		$this->set_mode($current_mode);
220
221
		// and re-encode
222
		return base64_encode($this->mcrypt_encode($dec, $key));
223
	}
224
225
	// --------------------------------------------------------------------
226
227
	/**
228
	 * XOR Encode
229
	 *
230
	 * Takes a plain-text string and key as input and generates an
231
	 * encoded bit-string using XOR
232
	 *
233
	 * @access	private
234
	 * @param	string
235
	 * @param	string
236
	 * @return	string
237
	 */
238
	function _xor_encode($string, $key)
239
	{
240
		$rand = '';
241
		while (strlen($rand) < 32)
242
		{
243
			$rand .= mt_rand(0, mt_getrandmax());
244
		}
245
246
		$rand = $this->hash($rand);
247
248
		$enc = '';
249
		for ($i = 0; $i < strlen($string); $i++)
250
		{
251
			$enc .= substr($rand, ($i % strlen($rand)), 1).(substr($rand, ($i % strlen($rand)), 1) ^ substr($string, $i, 1));
252
		}
253
254
		return $this->_xor_merge($enc, $key);
255
	}
256
257
	// --------------------------------------------------------------------
258
259
	/**
260
	 * XOR Decode
261
	 *
262
	 * Takes an encoded string and key as input and generates the
263
	 * plain-text original message
264
	 *
265
	 * @access	private
266
	 * @param	string
267
	 * @param	string
268
	 * @return	string
269
	 */
270
	function _xor_decode($string, $key)
271
	{
272
		$string = $this->_xor_merge($string, $key);
273
274
		$dec = '';
275
		for ($i = 0; $i < strlen($string); $i++)
276
		{
277
			$dec .= (substr($string, $i++, 1) ^ substr($string, $i, 1));
278
		}
279
280
		return $dec;
281
	}
282
283
	// --------------------------------------------------------------------
284
285
	/**
286
	 * XOR key + string Combiner
287
	 *
288
	 * Takes a string and key as input and computes the difference using XOR
289
	 *
290
	 * @access	private
291
	 * @param	string
292
	 * @param	string
293
	 * @return	string
294
	 */
295
	function _xor_merge($string, $key)
296
	{
297
		$hash = $this->hash($key);
298
		$str = '';
299
		for ($i = 0; $i < strlen($string); $i++)
300
		{
301
			$str .= substr($string, $i, 1) ^ substr($hash, ($i % strlen($hash)), 1);
302
		}
303
304
		return $str;
305
	}
306
307
	// --------------------------------------------------------------------
308
309
	/**
310
	 * Encrypt using Mcrypt
311
	 *
312
	 * @access	public
313
	 * @param	string
314
	 * @param	string
315
	 * @return	string
316
	 */
317
	function mcrypt_encode($data, $key)
318
	{
319
		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
320
		$init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
321
		return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key);
322
	}
323
324
	// --------------------------------------------------------------------
325
326
	/**
327
	 * Decrypt using Mcrypt
328
	 *
329
	 * @access	public
330
	 * @param	string
331
	 * @param	string
332
	 * @return	string
333
	 */
334
	function mcrypt_decode($data, $key)
335
	{
336
		$data = $this->_remove_cipher_noise($data, $key);
337
		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
338
339
		if ($init_size > strlen($data))
340
		{
341
			return FALSE;
342
		}
343
344
		$init_vect = substr($data, 0, $init_size);
345
		$data = substr($data, $init_size);
346
		return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");
347
	}
348
349
	// --------------------------------------------------------------------
350
351
	/**
352
	 * Adds permuted noise to the IV + encrypted data to protect
353
	 * against Man-in-the-middle attacks on CBC mode ciphers
354
	 * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV
355
	 *
356
	 * Function description
357
	 *
358
	 * @access	private
359
	 * @param	string
360
	 * @param	string
361
	 * @return	string
362
	 */
363
	function _add_cipher_noise($data, $key)
364
	{
365
		$keyhash = $this->hash($key);
366
		$keylen = strlen($keyhash);
367
		$str = '';
368
369
		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)
370
		{
371
			if ($j >= $keylen)
372
			{
373
				$j = 0;
374
			}
375
376
			$str .= chr((ord($data[$i]) + ord($keyhash[$j])) % 256);
377
		}
378
379
		return $str;
380
	}
381
382
	// --------------------------------------------------------------------
383
384
	/**
385
	 * Removes permuted noise from the IV + encrypted data, reversing
386
	 * _add_cipher_noise()
387
	 *
388
	 * Function description
389
	 *
390
	 * @access	public
391
	 * @param	type
392
	 * @return	type
393
	 */
394
	function _remove_cipher_noise($data, $key)
395
	{
396
		$keyhash = $this->hash($key);
397
		$keylen = strlen($keyhash);
398
		$str = '';
399
400
		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)
401
		{
402
			if ($j >= $keylen)
403
			{
404
				$j = 0;
405
			}
406
407
			$temp = ord($data[$i]) - ord($keyhash[$j]);
408
409
			if ($temp < 0)
410
			{
411
				$temp = $temp + 256;
412
			}
413
414
			$str .= chr($temp);
415
		}
416
417
		return $str;
418
	}
419
420
	// --------------------------------------------------------------------
421
422
	/**
423
	 * Set the Mcrypt Cipher
424
	 *
425
	 * @access	public
426
	 * @param	constant
427
	 * @return	string
428
	 */
429
	function set_cipher($cipher)
430
	{
431
		$this->_mcrypt_cipher = $cipher;
432
	}
433
434
	// --------------------------------------------------------------------
435
436
	/**
437
	 * Set the Mcrypt Mode
438
	 *
439
	 * @access	public
440
	 * @param	constant
441
	 * @return	string
442
	 */
443
	function set_mode($mode)
444
	{
445
		$this->_mcrypt_mode = $mode;
446
	}
447
448
	// --------------------------------------------------------------------
449
450
	/**
451
	 * Get Mcrypt cipher Value
452
	 *
453
	 * @access	private
454
	 * @return	string
455
	 */
456
	function _get_cipher()
457
	{
458
		if ($this->_mcrypt_cipher == '')
459
		{
460
			$this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;
461
		}
462
463
		return $this->_mcrypt_cipher;
464
	}
465
466
	// --------------------------------------------------------------------
467
468
	/**
469
	 * Get Mcrypt Mode Value
470
	 *
471
	 * @access	private
472
	 * @return	string
473
	 */
474
	function _get_mode()
475
	{
476
		if ($this->_mcrypt_mode == '')
477
		{
478
			$this->_mcrypt_mode = MCRYPT_MODE_CBC;
479
		}
480
481
		return $this->_mcrypt_mode;
482
	}
483
484
	// --------------------------------------------------------------------
485
486
	/**
487
	 * Set the Hash type
488
	 *
489
	 * @access	public
490
	 * @param	string
491
	 * @return	string
492
	 */
493
	function set_hash($type = 'sha1')
494
	{
495
		$this->_hash_type = ($type != 'sha1' AND $type != 'md5') ? 'sha1' : $type;
496
	}
497
498
	// --------------------------------------------------------------------
499
500
	/**
501
	 * Hash encode a string
502
	 *
503
	 * @access	public
504
	 * @param	string
505
	 * @return	string
506
	 */
507
	function hash($str)
508
	{
509
		return ($this->_hash_type == 'sha1') ? $this->sha1($str) : md5($str);
510
	}
511
512
	// --------------------------------------------------------------------
513
514
	/**
515
	 * Generate an SHA1 Hash
516
	 *
517
	 * @access	public
518
	 * @param	string
519
	 * @return	string
520
	 */
521
	function sha1($str)
522
	{
523
		if ( ! function_exists('sha1'))
524
		{
525
			if ( ! function_exists('mhash'))
526
			{
527
				require_once(BASEPATH.'libraries/Sha1.php');
528
				$SH = new CI_SHA;
529
				return $SH->generate($str);
530
			}
531
			else
532
			{
533
				return bin2hex(mhash(MHASH_SHA1, $str));
534
			}
535
		}
536
		else
537
		{
538
			return sha1($str);
539
		}
540
	}
541
542
}
543
544
// END CI_Encrypt class
545
546
/* End of file Encrypt.php */
547
/* Location: ./system/libraries/Encrypt.php */