Initial Kohana install
[speedfreak] / Server / system / libraries / Encrypt.php
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3  * The Encrypt library provides two-way encryption of text and binary strings
4  * using the MCrypt extension.
5  * @see http://php.net/mcrypt
6  *
7  * $Id: Encrypt.php 4072 2009-03-13 17:20:38Z jheathco $
8  *
9  * @package    Core
10  * @author     Kohana Team
11  * @copyright  (c) 2007-2008 Kohana Team
12  * @license    http://kohanaphp.com/license.html
13  */
14 class Encrypt_Core {
15
16         // OS-dependant RAND type to use
17         protected static $rand;
18
19         // Configuration
20         protected $config;
21
22         /**
23          * Returns a singleton instance of Encrypt.
24          *
25          * @param   array  configuration options
26          * @return  Encrypt_Core
27          */
28         public static function instance($config = NULL)
29         {
30                 static $instance;
31
32                 // Create the singleton
33                 empty($instance) and $instance = new Encrypt((array) $config);
34
35                 return $instance;
36         }
37
38         /**
39          * Loads encryption configuration and validates the data.
40          *
41          * @param   array|string      custom configuration or config group name
42          * @throws  Kohana_Exception
43          */
44         public function __construct($config = FALSE)
45         {
46                 if ( ! defined('MCRYPT_ENCRYPT'))
47                         throw new Kohana_Exception('encrypt.requires_mcrypt');
48
49                 if (is_string($config))
50                 {
51                         $name = $config;
52
53                         // Test the config group name
54                         if (($config = Kohana::config('encryption.'.$config)) === NULL)
55                                 throw new Kohana_Exception('encrypt.undefined_group', $name);
56                 }
57
58                 if (is_array($config))
59                 {
60                         // Append the default configuration options
61                         $config += Kohana::config('encryption.default');
62                 }
63                 else
64                 {
65                         // Load the default group
66                         $config = Kohana::config('encryption.default');
67                 }
68
69                 if (empty($config['key']))
70                         throw new Kohana_Exception('encrypt.no_encryption_key');
71
72                 // Find the max length of the key, based on cipher and mode
73                 $size = mcrypt_get_key_size($config['cipher'], $config['mode']);
74
75                 if (strlen($config['key']) > $size)
76                 {
77                         // Shorten the key to the maximum size
78                         $config['key'] = substr($config['key'], 0, $size);
79                 }
80
81                 // Find the initialization vector size
82                 $config['iv_size'] = mcrypt_get_iv_size($config['cipher'], $config['mode']);
83
84                 // Cache the config in the object
85                 $this->config = $config;
86
87                 Kohana::log('debug', 'Encrypt Library initialized');
88         }
89
90         /**
91          * Encrypts a string and returns an encrypted string that can be decoded.
92          *
93          * @param   string  data to be encrypted
94          * @return  string  encrypted data
95          */
96         public function encode($data)
97         {
98                 // Set the rand type if it has not already been set
99                 if (Encrypt::$rand === NULL)
100                 {
101                         if (KOHANA_IS_WIN)
102                         {
103                                 // Windows only supports the system random number generator
104                                 Encrypt::$rand = MCRYPT_RAND;
105                         }
106                         else
107                         {
108                                 if (defined('MCRYPT_DEV_URANDOM'))
109                                 {
110                                         // Use /dev/urandom
111                                         Encrypt::$rand = MCRYPT_DEV_URANDOM;
112                                 }
113                                 elseif (defined('MCRYPT_DEV_RANDOM'))
114                                 {
115                                         // Use /dev/random
116                                         Encrypt::$rand = MCRYPT_DEV_RANDOM;
117                                 }
118                                 else
119                                 {
120                                         // Use the system random number generator
121                                         Encrypt::$rand = MCRYPT_RAND;
122                                 }
123                         }
124                 }
125
126                 if (Encrypt::$rand === MCRYPT_RAND)
127                 {
128                         // The system random number generator must always be seeded each
129                         // time it is used, or it will not produce true random results
130                         mt_srand();
131                 }
132
133                 // Create a random initialization vector of the proper size for the current cipher
134                 $iv = mcrypt_create_iv($this->config['iv_size'], Encrypt::$rand);
135
136                 // Encrypt the data using the configured options and generated iv
137                 $data = mcrypt_encrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv);
138
139                 // Use base64 encoding to convert to a string
140                 return base64_encode($iv.$data);
141         }
142
143         /**
144          * Decrypts an encoded string back to its original value.
145          *
146          * @param   string  encoded string to be decrypted
147          * @return  string  decrypted data
148          */
149         public function decode($data)
150         {
151                 // Convert the data back to binary
152                 $data = base64_decode($data);
153
154                 // Extract the initialization vector from the data
155                 $iv = substr($data, 0, $this->config['iv_size']);
156
157                 // Remove the iv from the data
158                 $data = substr($data, $this->config['iv_size']);
159
160                 // Return the decrypted data, trimming the \0 padding bytes from the end of the data
161                 return rtrim(mcrypt_decrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv), "\0");
162         }
163
164 } // End Encrypt