Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 1 | ################## |
| 2 | Encryption Library |
| 3 | ################## |
| 4 | |
| 5 | The Encryption Library provides two-way data encryption. To do so in |
| 6 | a cryptographically secure way, it utilizes PHP extensions that are |
| 7 | unfortunately not always available on all systems. |
Andrey Andreev | 5b3fe7c | 2014-07-07 10:55:53 +0300 | [diff] [blame] | 8 | You must meet one of the following dependencies in order to use this |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 9 | library: |
| 10 | |
| 11 | - `OpenSSL <http://php.net/openssl>`_ (and PHP 5.3.3) |
| 12 | - `MCrypt <http://php.net/mcrypt>`_ (and `MCRYPT_DEV_URANDOM` availability) |
| 13 | |
Andrey Andreev | 5b3fe7c | 2014-07-07 10:55:53 +0300 | [diff] [blame] | 14 | If neither of the above dependencies is met, we simply cannot offer |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 15 | you a good enough implementation to meet the high standards required |
| 16 | for proper cryptography. |
| 17 | |
| 18 | .. contents:: |
| 19 | :local: |
| 20 | |
| 21 | .. raw:: html |
| 22 | |
| 23 | <div class="custom-index container"></div> |
| 24 | |
| 25 | **************************** |
| 26 | Using the Encryption Library |
| 27 | **************************** |
| 28 | |
| 29 | Initializing the Class |
| 30 | ====================== |
| 31 | |
| 32 | Like most other classes in CodeIgniter, the Encryption library is |
| 33 | initialized in your controller using the ``$this->load->library()`` |
| 34 | method:: |
| 35 | |
Kakysha | 8fe7b62 | 2014-04-19 18:01:04 +0400 | [diff] [blame] | 36 | $this->load->library('encryption'); |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 37 | |
| 38 | Once loaded, the Encryption library object will be available using:: |
| 39 | |
Kakysha | 8fe7b62 | 2014-04-19 18:01:04 +0400 | [diff] [blame] | 40 | $this->encryption |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 41 | |
| 42 | Default behavior |
| 43 | ================ |
| 44 | |
| 45 | By default, the Encryption Library will use the AES-128 cipher in CBC |
| 46 | mode, using your configured *encryption_key* and SHA512 HMAC authentication. |
| 47 | |
| 48 | .. note:: AES-128 is chosen both because it is proven to be strong and |
| 49 | because of its wide availability across different cryptographic |
| 50 | software and programming languages' APIs. |
| 51 | |
| 52 | However, the *encryption_key* is not used as is. |
| 53 | |
| 54 | If you are somewhat familiar with cryptography, you should already know |
| 55 | that a HMAC also requires a secret key and using the same key for both |
| 56 | encryption and authentication is a bad practice. |
| 57 | |
| 58 | Because of that, two separate keys are derived from your already configured |
| 59 | *encryption_key*: one for encryption and one for authentication. This is |
| 60 | done via a technique called `HMAC-based Key Derivation Function |
| 61 | <http://en.wikipedia.org/wiki/HKDF>`_ (HKDF). |
| 62 | |
| 63 | Setting your encryption_key |
| 64 | =========================== |
| 65 | |
| 66 | An *encryption key* is a piece of information that controls the |
| 67 | cryptographic process and permits a plain-text string to be encrypted, |
| 68 | and afterwards - decrypted. It is the secret "ingredient" in the whole |
| 69 | process that allows you to be the only one who is able to decrypt data |
| 70 | that you've decided to hide from the eyes of the public. |
| 71 | After one key is used to encrypt data, that same key provides the **only** |
| 72 | means to decrypt it, so not only must you chose one carefully, but you |
| 73 | must not lose it or you will also use the encrypted data. |
| 74 | |
| 75 | It must be noted that to ensure maximum security, such key *should* not |
| 76 | only be as strong as possible, but also often changed. Such behavior |
| 77 | however is rarely practical or possible to implement, and that is why |
| 78 | CodeIgniter gives you the ability to configure a single key that is to be |
| 79 | used (almost) every time. |
| 80 | |
| 81 | It goes without saying that you should guard your key carefully. Should |
| 82 | someone gain access to your key, the data will be easily decrypted. If |
| 83 | your server is not totally under your control it's impossible to ensure |
| 84 | key security so you may want to think carefully before using it for |
| 85 | anything that requires high security, like storing credit card numbers. |
| 86 | |
Andrey Andreev | 42183de | 2014-06-22 00:09:36 +0300 | [diff] [blame] | 87 | Your encryption key **must** be as long as the encyption algorithm in use |
| 88 | allows. For AES-128, that's 128 bits or 16 bytes (charcters) long. |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 89 | You will find a table below that shows the supported key lengths of |
| 90 | different ciphers. |
| 91 | |
Andrey Andreev | 42183de | 2014-06-22 00:09:36 +0300 | [diff] [blame] | 92 | The key should be as random as possible and it **must not** be a regular |
| 93 | text string, nor the output of a hashing function, etc. In order to create |
| 94 | a proper key, you must use the Encryption library's ``create_key()`` method |
| 95 | :: |
| 96 | |
| 97 | // $key will be assigned a 16-byte (128-bit) random key |
| 98 | $key = $this->encryption->create_key(16); |
| 99 | |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 100 | The key can be either stored in your *application/config/config.php*, or |
| 101 | you can design your own storage mechanism and pass the key dynamically |
| 102 | when encrypting/decrypting. |
| 103 | |
| 104 | To save your key to your *application/config/config.php*, open the file |
| 105 | and set:: |
| 106 | |
| 107 | $config['encryption_key'] = 'YOUR KEY'; |
| 108 | |
| 109 | .. _ciphers-and-modes: |
| 110 | |
| 111 | Supported encryption ciphers and modes |
| 112 | ====================================== |
| 113 | |
| 114 | .. note:: The terms 'cipher' and 'encryption algorithm' are interchangeable. |
| 115 | |
| 116 | Portable ciphers |
| 117 | ---------------- |
| 118 | |
| 119 | Because MCrypt and OpenSSL (also called drivers throughout this document) |
| 120 | each support different sets of encryption algorithms and often implement |
| 121 | them in different ways, our Encryption library is designed to use them in |
| 122 | a portable fashion, or in other words - it enables you to use them |
| 123 | interchangeably, at least for the ciphers supported by both drivers. |
| 124 | |
| 125 | It is also implemented in a way that aims to match the standard |
| 126 | implementations in other programming languages and libraries. |
| 127 | |
| 128 | Here's a list of the so called "portable" ciphers, where |
| 129 | "CodeIgniter name" is the string value that you'd have to pass to the |
| 130 | Encryption library to use that cipher: |
| 131 | |
| 132 | ======================== ================== ============================ =============================== |
| 133 | Cipher name CodeIgniter name Key lengths (bits / bytes) Supported modes |
| 134 | ======================== ================== ============================ =============================== |
| 135 | AES-128 / Rijndael-128 aes-128 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB |
| 136 | AES-192 aes-192 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB |
| 137 | AES-256 aes-256 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB |
| 138 | DES des 56 / 7 CBC, CFB, CFB8, OFB, ECB |
| 139 | TripleDES tripledes 56 / 7, 112 / 14, 168 / 21 CBC, CFB, CFB8, OFB |
| 140 | Blowfish blowfish 128-448 / 16-56 CBC, CFB, OFB, ECB |
Andrey Andreev | 18767e3 | 2014-03-04 22:21:35 +0200 | [diff] [blame] | 141 | CAST5 / CAST-128 cast5 88-128 / 11-16 CBC, CFB, OFB, ECB |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 142 | RC4 / ARCFour rc4 40-2048 / 5-256 Stream |
| 143 | ======================== ================== ============================ =============================== |
| 144 | |
| 145 | .. important:: Because of how MCrypt works, if you fail to provide a key |
| 146 | with the appropriate length, you might end up using a different |
| 147 | algorithm than the one configured, so be really careful with that! |
| 148 | |
| 149 | .. note:: In case it isn't clear from the above table, Blowfish, CAST5 |
| 150 | and RC4 support variable length keys. That is, any number in the |
| 151 | shown ranges is valid, although in bit terms that only happens |
| 152 | in 8-bit increments. |
| 153 | |
| 154 | .. note:: Even though CAST5 supports key lengths lower than 128 bits |
| 155 | (16 bytes), in fact they will just be zero-padded to the |
| 156 | maximum length, as specified in `RFC 2144 |
| 157 | <http://tools.ietf.org/rfc/rfc2144.txt>`_. |
| 158 | |
| 159 | .. note:: Blowfish supports key lengths as small as 32 bits (4 bytes), but |
| 160 | our tests have shown that only lengths of 128 bits (16 bytes) or |
| 161 | higher are properly supported by both MCrypt and OpenSSL. It is |
| 162 | also a bad practice to use such low-length keys anyway. |
| 163 | |
| 164 | Driver-specific ciphers |
| 165 | ----------------------- |
| 166 | |
| 167 | As noted above, MCrypt and OpenSSL support different sets of encryption |
| 168 | ciphers. For portability reasons and because we haven't tested them |
| 169 | properly, we do not advise you to use the ones that are driver-specific, |
| 170 | but regardless, here's a list of most of them: |
| 171 | |
| 172 | |
| 173 | ============== ========= ============================== ========================================= |
| 174 | Cipher name Driver Key lengths (bits / bytes) Supported modes |
| 175 | ============== ========= ============================== ========================================= |
Andrey Andreev | ab9971f | 2014-07-02 19:09:08 +0300 | [diff] [blame] | 176 | AES-128 OpenSSL 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB, XTS |
| 177 | AES-192 OpenSSL 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB, XTS |
| 178 | AES-256 OpenSSL 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB, XTS |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 179 | Rijndael-128 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 180 | Rijndael-192 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 181 | Rijndael-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 182 | GOST MCrypt 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 183 | Twofish MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
Andrey Andreev | 18767e3 | 2014-03-04 22:21:35 +0200 | [diff] [blame] | 184 | CAST-128 MCrypt 40-128 / 5-16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 185 | CAST-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 186 | Loki97 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 187 | SaferPlus MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 188 | Serpent MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 189 | XTEA MCrypt 128 / 16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 190 | RC2 MCrypt 8-1024 / 1-128 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB |
| 191 | RC2 OpenSSL 8-1024 / 1-128 CBC, CFB, OFB, ECB |
| 192 | Camellia-128 OpenSSL 128 / 16 CBC, CFB, CFB8, OFB, ECB |
| 193 | Camellia-192 OpenSSL 192 / 24 CBC, CFB, CFB8, OFB, ECB |
| 194 | Camellia-256 OpenSSL 256 / 32 CBC, CFB, CFB8, OFB, ECB |
| 195 | Seed OpenSSL 128 / 16 CBC, CFB, OFB, ECB |
| 196 | ============== ========= ============================== ========================================= |
| 197 | |
| 198 | .. note:: If you wish to use one of those ciphers, you'd have to pass |
| 199 | its name in lower-case to the Encryption library. |
| 200 | |
| 201 | .. note:: You've probably noticed that all AES cipers (and Rijndael-128) |
| 202 | are also listed in the portable ciphers list. This is because |
| 203 | drivers support different modes for these ciphers. Also, it is |
| 204 | important to note that AES-128 and Rijndael-128 are actually |
| 205 | the same cipher, but **only** when used with a 128-bit key. |
| 206 | |
Andrey Andreev | 18767e3 | 2014-03-04 22:21:35 +0200 | [diff] [blame] | 207 | .. note:: CAST-128 / CAST-5 is also listed in both the portable and |
| 208 | driver-specific ciphers list. This is because OpenSSL's |
| 209 | implementation doesn't appear to be working correctly with |
| 210 | key sizes of 80 bits and lower. |
| 211 | |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 212 | .. note:: RC2 is listed as supported by both MCrypt and OpenSSL. |
| 213 | However, both drivers implement them differently and they |
| 214 | are not portable. It is probably worth noting that we only |
| 215 | found one obscure source confirming that it is MCrypt that |
| 216 | is not properly implementing it. |
| 217 | |
| 218 | .. _encryption-modes: |
| 219 | |
| 220 | Encryption modes |
| 221 | ---------------- |
| 222 | |
| 223 | Different modes of encryption have different characteristics and serve |
| 224 | for different purposes. Some are stronger than others, some are faster |
| 225 | and some offer extra features. |
| 226 | We are not going in depth into that here, we'll leave that to the |
| 227 | cryptography experts. The table below is to provide brief informational |
| 228 | reference to our more experienced users. If you are a beginner, just |
| 229 | stick to the CBC mode - it is widely accepted as strong and secure for |
| 230 | general purposes. |
| 231 | |
| 232 | =========== ================== ================= =================================================================================================================================================== |
| 233 | Mode name CodeIgniter name Driver support Additional info |
| 234 | =========== ================== ================= =================================================================================================================================================== |
| 235 | CBC cbc MCrypt, OpenSSL A safe default choice |
| 236 | CTR ctr MCrypt, OpenSSL Considered as theoretically better than CBC, but not as widely available |
| 237 | CFB cfb MCrypt, OpenSSL N/A |
| 238 | CFB8 cfb8 MCrypt, OpenSSL Same as CFB, but operates in 8-bit mode (not recommended). |
| 239 | OFB ofb MCrypt, OpenSSL N/A |
| 240 | OFB8 ofb8 MCrypt Same as OFB, but operates in 8-bit mode (not recommended). |
| 241 | ECB ecb MCrypt, OpenSSL Ignores IV (not recommended). |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 242 | XTS xts OpenSSL Usually used for encrypting random access data such as RAM or hard-disk storage. |
| 243 | Stream stream MCrypt, OpenSSL This is not actually a mode, it just says that a stream cipher is being used. Required because of the general cipher+mode initialization process. |
| 244 | =========== ================== ================= =================================================================================================================================================== |
| 245 | |
| 246 | Message Length |
| 247 | ============== |
| 248 | |
| 249 | It's probably important for you to know that an encrypted string is usually |
| 250 | longer than the original, plain-text string (depending on the cipher). |
| 251 | |
| 252 | This is influenced by the cipher algorithm itself, the IV prepended to the |
Andrey Andreev | ab9971f | 2014-07-02 19:09:08 +0300 | [diff] [blame] | 253 | cipher-text and the HMAC authentication message that is also prepended. |
| 254 | Furthermore, the encrypted message is also Base64-encoded so that it is safe |
| 255 | for storage and transmission, regardless of a possible character set in use. |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 256 | |
| 257 | Keep this information in mind when selecting your data storage mechanism. |
| 258 | Cookies, for example, can only hold 4K of information. |
| 259 | |
| 260 | .. _configuration: |
| 261 | |
| 262 | Configuring the library |
| 263 | ======================= |
| 264 | |
| 265 | For usability, performance, but also historical reasons tied to our old |
| 266 | :doc:`Encrypt Class <encrypt>`, the Encryption library is designed to |
| 267 | use repeatedly the same driver, encryption cipher, mode and key. |
| 268 | |
| 269 | As noted in the "Default behavior" section above, this means using an |
| 270 | auto-detected driver (OpenSSL has a higher priority), the AES-128 ciper |
| 271 | in CBC mode, and your ``$config['encryption_key']`` value. |
| 272 | |
| 273 | If you wish to change that however, you need to use the ``initialize()`` |
| 274 | method. It accepts an associative array of parameters, all of which are |
| 275 | optional: |
| 276 | |
| 277 | ======== =============================================== |
| 278 | Option Possible values |
| 279 | ======== =============================================== |
| 280 | driver 'mcrypt', 'openssl' |
| 281 | cipher Cipher name (see :ref:`ciphers-and-modes`) |
| 282 | mode Encryption mode (see :ref:`encryption-modes`) |
| 283 | key Encryption key |
| 284 | ======== =============================================== |
| 285 | |
| 286 | For example, if you were to change the encryption algorithm and |
| 287 | mode to AES-256 in CTR mode, this is what you should do:: |
| 288 | |
| 289 | $this->encryption->initialize( |
| 290 | array( |
| 291 | 'cipher' => 'aes-256', |
| 292 | 'mode' => 'ctr', |
| 293 | 'key' => '<a 32-character random string>' |
| 294 | ) |
| 295 | ); |
| 296 | |
| 297 | Note that we only mentioned that you want to change the ciper and mode, |
| 298 | but we also included a key in the example. As previously noted, it is |
| 299 | important that you choose a key with a proper size for the used algorithm. |
| 300 | |
| 301 | There's also the ability to change the driver, if for some reason you |
| 302 | have both, but want to use MCrypt instead of OpenSSL:: |
| 303 | |
| 304 | // Switch to the MCrypt driver |
| 305 | $this->encryption->initialize(array('driver' => 'mcrypt')); |
| 306 | |
| 307 | // Switch back to the OpenSSL driver |
| 308 | $this->encryption->initialize(array('driver' => 'openssl')); |
| 309 | |
| 310 | Encrypting and decrypting data |
| 311 | ============================== |
| 312 | |
| 313 | Encrypting and decrypting data with the already configured library |
| 314 | settings is simple. As simple as just passing the string to the |
| 315 | ``encrypt()`` and/or ``decrypt()`` methods:: |
| 316 | |
| 317 | $plain_text = 'This is a plain-text message!'; |
| 318 | $ciphertext = $this->encryption->encrypt($plain_text); |
| 319 | |
| 320 | // Outputs: This is a plain-text message! |
| 321 | echo $this->encryption->decrypt($ciphertext); |
| 322 | |
| 323 | And that's it! The Encryption library will do everything necessary |
| 324 | for the whole process to be cryptographically secure out-of-the-box. |
| 325 | You don't need to worry about it. |
| 326 | |
| 327 | .. important:: Both methods will return FALSE in case of an error. |
| 328 | While for ``encrypt()`` this can only mean incorrect |
| 329 | configuration, you should always check the return value |
| 330 | of ``decrypt()`` in production code. |
| 331 | |
| 332 | How it works |
| 333 | ------------ |
| 334 | |
| 335 | If you must know how the process works, here's what happens under |
| 336 | the hood: |
| 337 | |
| 338 | - ``$this->encryption->encrypt($plain_text)`` |
| 339 | |
| 340 | #. Derive an encryption key and a HMAC key from your configured |
| 341 | *encryption_key* via HKDF, using the SHA-512 digest algorithm. |
| 342 | |
| 343 | #. Generate a random initialization vector (IV). |
| 344 | |
| 345 | #. Encrypt the data via AES-128 in CBC mode (or another previously |
| 346 | configured cipher and mode), using the above-mentioned derived |
| 347 | encryption key and IV. |
| 348 | |
| 349 | #. Prepend said IV to the resulting cipher-text. |
| 350 | |
| 351 | #. Base64-encode the resulting string, so that it can be safely |
| 352 | stored or transferred without worrying about character sets. |
| 353 | |
| 354 | #. Create a SHA-512 HMAC authentication message using the derived |
| 355 | HMAC key to ensure data integrity and prepend it to the Base64 |
| 356 | string. |
| 357 | |
| 358 | - ``$this->encryption->decrypt($ciphertext)`` |
| 359 | |
| 360 | #. Derive an encryption key and a HMAC key from your configured |
| 361 | *encryption_key* via HKDF, using the SHA-512 digest algorithm. |
| 362 | Because your configured *encryption_key* is the same, this |
| 363 | will produce the same result as in the ``encrypt()`` method |
| 364 | above - otherwise you won't be able to decrypt it. |
| 365 | |
| 366 | #. Check if the string is long enough, separate the HMAC out of |
| 367 | it and validate if it is correct (this is done in a way that |
| 368 | prevents timing attacks agains it). Return FALSE if either of |
| 369 | the checks fails. |
| 370 | |
| 371 | #. Base64-decode the string. |
| 372 | |
| 373 | #. Separate the IV out of the cipher-text and decrypt the said |
| 374 | cipher-text using that IV and the derived encryption key. |
| 375 | |
| 376 | .. _custom-parameters: |
| 377 | |
| 378 | Using custom parameters |
| 379 | ----------------------- |
| 380 | |
| 381 | Let's say you have to interact with another system that is out |
| 382 | of your control and uses another method to encrypt data. A |
| 383 | method that will most certainly not match the above-described |
| 384 | sequence and probably not use all of the steps either. |
| 385 | |
| 386 | The Encryption library allows you to change how its encryption |
| 387 | and decryption processes work, so that you can easily tailor a |
| 388 | custom solution for such situations. |
| 389 | |
| 390 | .. note:: It is possible to use the library in this way, without |
| 391 | setting an *encryption_key* in your configuration file. |
| 392 | |
| 393 | All you have to do is to pass an associative array with a few |
| 394 | parameters to either the ``encrypt()`` or ``decrypt()`` method. |
| 395 | Here's an example:: |
| 396 | |
| 397 | // Assume that we have $ciphertext, $key and $hmac_key |
| 398 | // from on outside source |
| 399 | |
| 400 | $message = $this->encryption->decrypt( |
| 401 | $ciphertext, |
| 402 | array( |
| 403 | 'cipher' => 'blowfish', |
| 404 | 'mode' => 'cbc', |
| 405 | 'key' => $key, |
| 406 | 'hmac_digest' => 'sha256', |
| 407 | 'hmac_key' => $hmac_key |
| 408 | ) |
| 409 | ); |
| 410 | |
| 411 | In the above example, we are decrypting a message that was encrypted |
| 412 | using the Blowfish cipher in CBC mode and authenticated via a SHA-256 |
| 413 | HMAC. |
| 414 | |
| 415 | .. important:: Note that both 'key' and 'hmac_key' are used in this |
| 416 | example. When using custom parameters, encryption and HMAC keys |
| 417 | are not derived like the default behavior of the library is. |
| 418 | |
| 419 | Below is a list of the available options. |
| 420 | |
| 421 | However, unless you really need to and you know what you are doing, |
| 422 | we advise you to not change the encryption process as this could |
| 423 | impact security, so please do so with caution. |
| 424 | |
| 425 | ============= =============== ============================= ====================================================== |
| 426 | Option Default value Mandatory / Optional Description |
| 427 | ============= =============== ============================= ====================================================== |
| 428 | cipher N/A Yes Encryption algorithm (see :ref:`ciphers-and-modes`). |
| 429 | mode N/A Yes Encryption mode (see :ref:`encryption-modes`). |
| 430 | key N/A Yes Encryption key. |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 431 | hmac TRUE No Whether to use a HMAC. |
| 432 | Boolean. If set to FALSE, then *hmac_digest* and |
| 433 | *hmac_key* will be ignored. |
| 434 | hmac_digest sha512 No HMAC message digest algorithm (see :ref:`digests`). |
| 435 | hmac_key N/A Yes, unless *hmac* is FALSE HMAC key. |
| 436 | raw_data FALSE No Whether the cipher-text should be raw. |
| 437 | Boolean. If set to TRUE, then Base64 encoding and |
| 438 | decoding will not be performed and HMAC will not |
| 439 | be a hexadecimal string. |
| 440 | ============= =============== ============================= ====================================================== |
| 441 | |
| 442 | .. important:: ``encrypt()`` and ``decrypt()`` will return FALSE if |
| 443 | a mandatory parameter is not provided or if a provided |
| 444 | value is incorrect. This includes *hmac_key*, unless *hmac* |
| 445 | is set to FALSE. |
| 446 | |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 447 | .. _digests: |
| 448 | |
| 449 | Supported HMAC authentication algorithms |
| 450 | ---------------------------------------- |
| 451 | |
| 452 | For HMAC message authentication, the Encryption library supports |
| 453 | usage of the SHA-2 family of algorithms: |
| 454 | |
| 455 | =========== ==================== ============================ |
| 456 | Algorithm Raw length (bytes) Hex-encoded length (bytes) |
| 457 | =========== ==================== ============================ |
| 458 | sha512 64 128 |
| 459 | sha384 48 96 |
| 460 | sha256 32 64 |
| 461 | sha224 28 56 |
| 462 | =========== ==================== ============================ |
| 463 | |
| 464 | The reason for not including other popular algorithms, such as |
| 465 | MD5 or SHA1 is that they are no longer considered secure enough |
| 466 | and as such, we don't want to encourage their usage. |
| 467 | If you absolutely need to use them, it is easy to do so via PHP's |
| 468 | native `hash_hmac() <http://php.net/hash_hmac()>`_ function. |
| 469 | |
| 470 | Stronger algorithms of course will be added in the future as they |
| 471 | appear and become widely available. |
| 472 | |
| 473 | *************** |
| 474 | Class Reference |
| 475 | *************** |
| 476 | |
Andrey Andreev | cd3d9db | 2015-02-02 13:41:01 +0200 | [diff] [blame] | 477 | .. php:class:: CI_Encryption |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 478 | |
Andrey Andreev | cd3d9db | 2015-02-02 13:41:01 +0200 | [diff] [blame] | 479 | .. php:method:: initialize($params) |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 480 | |
| 481 | :param array $params: Configuration parameters |
| 482 | :returns: CI_Encryption instance (method chaining) |
| 483 | :rtype: CI_Encryption |
| 484 | |
| 485 | Initializes (configures) the library to use a different |
| 486 | driver, cipher, mode or key. |
| 487 | |
| 488 | Example:: |
| 489 | |
| 490 | $this->encryption->initialize( |
| 491 | array('mode' => 'ctr') |
| 492 | ); |
| 493 | |
| 494 | Please refer to the :ref:`configuration` section for detailed info. |
| 495 | |
Andrey Andreev | cd3d9db | 2015-02-02 13:41:01 +0200 | [diff] [blame] | 496 | .. php:method:: encrypt($data[, $params = NULL]) |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 497 | |
| 498 | :param string $data: Data to encrypt |
| 499 | :param array $params: Optional parameters |
| 500 | :returns: Encrypted data or FALSE on failure |
| 501 | :rtype: string |
| 502 | |
| 503 | Encrypts the input data and returns its ciphertext. |
| 504 | |
| 505 | Example:: |
| 506 | |
| 507 | $ciphertext = $this->encryption->encrypt('My secret message'); |
| 508 | |
| 509 | Please refer to the :ref:`custom-parameters` section for information |
| 510 | on the optional parameters. |
| 511 | |
Andrey Andreev | cd3d9db | 2015-02-02 13:41:01 +0200 | [diff] [blame] | 512 | .. php:method:: decrypt($data[, $params = NULL]) |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 513 | |
| 514 | :param string $data: Data to decrypt |
| 515 | :param array $params: Optional parameters |
| 516 | :returns: Decrypted data or FALSE on failure |
| 517 | :rtype: string |
| 518 | |
| 519 | Decrypts the input data and returns it in plain-text. |
| 520 | |
| 521 | Example:: |
| 522 | |
| 523 | echo $this->encryption->decrypt($ciphertext); |
| 524 | |
| 525 | Please refer to the :ref:`custom-parameters` secrion for information |
| 526 | on the optional parameters. |
| 527 | |
Andrey Andreev | cd3d9db | 2015-02-02 13:41:01 +0200 | [diff] [blame] | 528 | .. php:method:: hkdf($key[, $digest = 'sha512'[, $salt = NULL[, $length = NULL[, $info = '']]]]) |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 529 | |
| 530 | :param string $key: Input key material |
| 531 | :param string $digest: A SHA-2 family digest algorithm |
| 532 | :param string $salt: Optional salt |
| 533 | :param int $length: Optional output length |
| 534 | :param string $info: Optional context/application-specific info |
| 535 | :returns: A pseudo-random key or FALSE on failure |
Andrey Andreev | b906149 | 2014-12-04 16:33:24 +0200 | [diff] [blame] | 536 | :rtype: string |
Andrey Andreev | 4b45065 | 2014-02-10 06:59:54 +0200 | [diff] [blame] | 537 | |
| 538 | Derives a key from another, presumably weaker key. |
| 539 | |
| 540 | This method is used internally to derive an encryption and HMAC key |
| 541 | from your configured *encryption_key*. |
| 542 | |
| 543 | It is publicly available due to its otherwise general purpose. It is |
| 544 | described in `RFC 5869 <https://tools.ietf.org/rfc/rfc5869.txt>`_. |
| 545 | |
| 546 | However, as opposed to the description in RFC 5869, this implementation |
| 547 | doesn't support SHA1. |
| 548 | |
| 549 | Example:: |
| 550 | |
| 551 | $hmac_key = $this->encryption->hkdf( |
| 552 | $key, |
| 553 | 'sha512', |
| 554 | NULL, |
| 555 | NULL, |
| 556 | 'authentication' |
| 557 | ); |
| 558 | |
| 559 | // $hmac_key is a pseudo-random key with a length of 64 bytes |