blob: 2d0ee23a30c639475f290137133376dcb3687806 [file] [log] [blame]
Andrey Andreev4b450652014-02-10 06:59:54 +02001##################
2Encryption Library
3##################
4
5The Encryption Library provides two-way data encryption. To do so in
6a cryptographically secure way, it utilizes PHP extensions that are
7unfortunately not always available on all systems.
Andrey Andreev5b3fe7c2014-07-07 10:55:53 +03008You must meet one of the following dependencies in order to use this
Andrey Andreev4b450652014-02-10 06:59:54 +02009library:
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 Andreev5b3fe7c2014-07-07 10:55:53 +030014If neither of the above dependencies is met, we simply cannot offer
Andrey Andreev4b450652014-02-10 06:59:54 +020015you a good enough implementation to meet the high standards required
16for proper cryptography.
17
18.. contents::
19 :local:
20
21.. raw:: html
22
23 <div class="custom-index container"></div>
24
25****************************
26Using the Encryption Library
27****************************
28
29Initializing the Class
30======================
31
32Like most other classes in CodeIgniter, the Encryption library is
33initialized in your controller using the ``$this->load->library()``
34method::
35
Kakysha8fe7b622014-04-19 18:01:04 +040036 $this->load->library('encryption');
Andrey Andreev4b450652014-02-10 06:59:54 +020037
38Once loaded, the Encryption library object will be available using::
39
Kakysha8fe7b622014-04-19 18:01:04 +040040 $this->encryption
Andrey Andreev4b450652014-02-10 06:59:54 +020041
42Default behavior
43================
44
45By default, the Encryption Library will use the AES-128 cipher in CBC
46mode, 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
52However, the *encryption_key* is not used as is.
53
54If you are somewhat familiar with cryptography, you should already know
55that a HMAC also requires a secret key and using the same key for both
56encryption and authentication is a bad practice.
57
58Because of that, two separate keys are derived from your already configured
59*encryption_key*: one for encryption and one for authentication. This is
60done via a technique called `HMAC-based Key Derivation Function
61<http://en.wikipedia.org/wiki/HKDF>`_ (HKDF).
62
63Setting your encryption_key
64===========================
65
66An *encryption key* is a piece of information that controls the
67cryptographic process and permits a plain-text string to be encrypted,
68and afterwards - decrypted. It is the secret "ingredient" in the whole
69process that allows you to be the only one who is able to decrypt data
70that you've decided to hide from the eyes of the public.
71After one key is used to encrypt data, that same key provides the **only**
72means to decrypt it, so not only must you chose one carefully, but you
73must not lose it or you will also use the encrypted data.
74
75It must be noted that to ensure maximum security, such key *should* not
76only be as strong as possible, but also often changed. Such behavior
77however is rarely practical or possible to implement, and that is why
78CodeIgniter gives you the ability to configure a single key that is to be
79used (almost) every time.
80
81It goes without saying that you should guard your key carefully. Should
82someone gain access to your key, the data will be easily decrypted. If
83your server is not totally under your control it's impossible to ensure
84key security so you may want to think carefully before using it for
85anything that requires high security, like storing credit card numbers.
86
Andrey Andreev42183de2014-06-22 00:09:36 +030087Your encryption key **must** be as long as the encyption algorithm in use
88allows. For AES-128, that's 128 bits or 16 bytes (charcters) long.
Andrey Andreev4b450652014-02-10 06:59:54 +020089You will find a table below that shows the supported key lengths of
90different ciphers.
91
Andrey Andreev42183de2014-06-22 00:09:36 +030092The key should be as random as possible and it **must not** be a regular
93text string, nor the output of a hashing function, etc. In order to create
94a 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 Andreev4b450652014-02-10 06:59:54 +0200100The key can be either stored in your *application/config/config.php*, or
101you can design your own storage mechanism and pass the key dynamically
102when encrypting/decrypting.
103
104To save your key to your *application/config/config.php*, open the file
105and set::
106
107 $config['encryption_key'] = 'YOUR KEY';
108
109.. _ciphers-and-modes:
110
111Supported encryption ciphers and modes
112======================================
113
114.. note:: The terms 'cipher' and 'encryption algorithm' are interchangeable.
115
116Portable ciphers
117----------------
118
119Because MCrypt and OpenSSL (also called drivers throughout this document)
120each support different sets of encryption algorithms and often implement
121them in different ways, our Encryption library is designed to use them in
122a portable fashion, or in other words - it enables you to use them
123interchangeably, at least for the ciphers supported by both drivers.
124
125It is also implemented in a way that aims to match the standard
126implementations in other programming languages and libraries.
127
128Here'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
130Encryption library to use that cipher:
131
132======================== ================== ============================ ===============================
133Cipher name CodeIgniter name Key lengths (bits / bytes) Supported modes
134======================== ================== ============================ ===============================
135AES-128 / Rijndael-128 aes-128 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB
136AES-192 aes-192 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB
137AES-256 aes-256 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB
138DES des 56 / 7 CBC, CFB, CFB8, OFB, ECB
139TripleDES tripledes 56 / 7, 112 / 14, 168 / 21 CBC, CFB, CFB8, OFB
140Blowfish blowfish 128-448 / 16-56 CBC, CFB, OFB, ECB
Andrey Andreev18767e32014-03-04 22:21:35 +0200141CAST5 / CAST-128 cast5 88-128 / 11-16 CBC, CFB, OFB, ECB
Andrey Andreev4b450652014-02-10 06:59:54 +0200142RC4 / 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
164Driver-specific ciphers
165-----------------------
166
167As noted above, MCrypt and OpenSSL support different sets of encryption
168ciphers. For portability reasons and because we haven't tested them
169properly, we do not advise you to use the ones that are driver-specific,
170but regardless, here's a list of most of them:
171
172
173============== ========= ============================== =========================================
174Cipher name Driver Key lengths (bits / bytes) Supported modes
175============== ========= ============================== =========================================
Andrey Andreevab9971f2014-07-02 19:09:08 +0300176AES-128 OpenSSL 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
177AES-192 OpenSSL 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
178AES-256 OpenSSL 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
Andrey Andreev4b450652014-02-10 06:59:54 +0200179Rijndael-128 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
180Rijndael-192 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
181Rijndael-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
182GOST MCrypt 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
183Twofish MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
Andrey Andreev18767e32014-03-04 22:21:35 +0200184CAST-128 MCrypt 40-128 / 5-16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
Andrey Andreev4b450652014-02-10 06:59:54 +0200185CAST-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
186Loki97 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
187SaferPlus MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
188Serpent MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
189XTEA MCrypt 128 / 16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
190RC2 MCrypt 8-1024 / 1-128 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
191RC2 OpenSSL 8-1024 / 1-128 CBC, CFB, OFB, ECB
192Camellia-128 OpenSSL 128 / 16 CBC, CFB, CFB8, OFB, ECB
193Camellia-192 OpenSSL 192 / 24 CBC, CFB, CFB8, OFB, ECB
194Camellia-256 OpenSSL 256 / 32 CBC, CFB, CFB8, OFB, ECB
195Seed 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 Andreev18767e32014-03-04 22:21:35 +0200207.. 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 Andreev4b450652014-02-10 06:59:54 +0200212.. 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
220Encryption modes
221----------------
222
223Different modes of encryption have different characteristics and serve
224for different purposes. Some are stronger than others, some are faster
225and some offer extra features.
226We are not going in depth into that here, we'll leave that to the
227cryptography experts. The table below is to provide brief informational
228reference to our more experienced users. If you are a beginner, just
229stick to the CBC mode - it is widely accepted as strong and secure for
230general purposes.
231
232=========== ================== ================= ===================================================================================================================================================
233Mode name CodeIgniter name Driver support Additional info
234=========== ================== ================= ===================================================================================================================================================
235CBC cbc MCrypt, OpenSSL A safe default choice
236CTR ctr MCrypt, OpenSSL Considered as theoretically better than CBC, but not as widely available
237CFB cfb MCrypt, OpenSSL N/A
238CFB8 cfb8 MCrypt, OpenSSL Same as CFB, but operates in 8-bit mode (not recommended).
239OFB ofb MCrypt, OpenSSL N/A
240OFB8 ofb8 MCrypt Same as OFB, but operates in 8-bit mode (not recommended).
241ECB ecb MCrypt, OpenSSL Ignores IV (not recommended).
Andrey Andreev4b450652014-02-10 06:59:54 +0200242XTS xts OpenSSL Usually used for encrypting random access data such as RAM or hard-disk storage.
243Stream 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
246Message Length
247==============
248
249It's probably important for you to know that an encrypted string is usually
250longer than the original, plain-text string (depending on the cipher).
251
252This is influenced by the cipher algorithm itself, the IV prepended to the
Andrey Andreevab9971f2014-07-02 19:09:08 +0300253cipher-text and the HMAC authentication message that is also prepended.
254Furthermore, the encrypted message is also Base64-encoded so that it is safe
255for storage and transmission, regardless of a possible character set in use.
Andrey Andreev4b450652014-02-10 06:59:54 +0200256
257Keep this information in mind when selecting your data storage mechanism.
258Cookies, for example, can only hold 4K of information.
259
260.. _configuration:
261
262Configuring the library
263=======================
264
265For usability, performance, but also historical reasons tied to our old
266:doc:`Encrypt Class <encrypt>`, the Encryption library is designed to
267use repeatedly the same driver, encryption cipher, mode and key.
268
269As noted in the "Default behavior" section above, this means using an
270auto-detected driver (OpenSSL has a higher priority), the AES-128 ciper
271in CBC mode, and your ``$config['encryption_key']`` value.
272
273If you wish to change that however, you need to use the ``initialize()``
274method. It accepts an associative array of parameters, all of which are
275optional:
276
277======== ===============================================
278Option Possible values
279======== ===============================================
280driver 'mcrypt', 'openssl'
281cipher Cipher name (see :ref:`ciphers-and-modes`)
282mode Encryption mode (see :ref:`encryption-modes`)
283key Encryption key
284======== ===============================================
285
286For example, if you were to change the encryption algorithm and
287mode 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
297Note that we only mentioned that you want to change the ciper and mode,
298but we also included a key in the example. As previously noted, it is
299important that you choose a key with a proper size for the used algorithm.
300
301There's also the ability to change the driver, if for some reason you
302have 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
310Encrypting and decrypting data
311==============================
312
313Encrypting and decrypting data with the already configured library
314settings 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
323And that's it! The Encryption library will do everything necessary
324for the whole process to be cryptographically secure out-of-the-box.
325You 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
332How it works
333------------
334
335If you must know how the process works, here's what happens under
336the 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
378Using custom parameters
379-----------------------
380
381Let's say you have to interact with another system that is out
382of your control and uses another method to encrypt data. A
383method that will most certainly not match the above-described
384sequence and probably not use all of the steps either.
385
386The Encryption library allows you to change how its encryption
387and decryption processes work, so that you can easily tailor a
388custom 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
393All you have to do is to pass an associative array with a few
394parameters to either the ``encrypt()`` or ``decrypt()`` method.
395Here'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
411In the above example, we are decrypting a message that was encrypted
412using the Blowfish cipher in CBC mode and authenticated via a SHA-256
413HMAC.
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
419Below is a list of the available options.
420
421However, unless you really need to and you know what you are doing,
422we advise you to not change the encryption process as this could
423impact security, so please do so with caution.
424
425============= =============== ============================= ======================================================
426Option Default value Mandatory / Optional Description
427============= =============== ============================= ======================================================
428cipher N/A Yes Encryption algorithm (see :ref:`ciphers-and-modes`).
429mode N/A Yes Encryption mode (see :ref:`encryption-modes`).
430key N/A Yes Encryption key.
Andrey Andreev4b450652014-02-10 06:59:54 +0200431hmac TRUE No Whether to use a HMAC.
432 Boolean. If set to FALSE, then *hmac_digest* and
433 *hmac_key* will be ignored.
434hmac_digest sha512 No HMAC message digest algorithm (see :ref:`digests`).
435hmac_key N/A Yes, unless *hmac* is FALSE HMAC key.
436raw_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 Andreev4b450652014-02-10 06:59:54 +0200447.. _digests:
448
449Supported HMAC authentication algorithms
450----------------------------------------
451
452For HMAC message authentication, the Encryption library supports
453usage of the SHA-2 family of algorithms:
454
455=========== ==================== ============================
456Algorithm Raw length (bytes) Hex-encoded length (bytes)
457=========== ==================== ============================
458sha512 64 128
459sha384 48 96
460sha256 32 64
461sha224 28 56
462=========== ==================== ============================
463
464The reason for not including other popular algorithms, such as
465MD5 or SHA1 is that they are no longer considered secure enough
466and as such, we don't want to encourage their usage.
467If you absolutely need to use them, it is easy to do so via PHP's
468native `hash_hmac() <http://php.net/hash_hmac()>`_ function.
469
470Stronger algorithms of course will be added in the future as they
471appear and become widely available.
472
473***************
474Class Reference
475***************
476
477.. class:: CI_Encryption
478
479 .. method:: initialize($params)
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
496 .. method:: encrypt($data[, $params = NULL])
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
512 .. method:: decrypt($data[, $params = NULL])
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
528 .. method:: hkdf($key[, $digest = 'sha512'[, $salt = NULL[, $length = NULL[, $info = '']]]])
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 Andreevb9061492014-12-04 16:33:24 +0200536 :rtype: string
Andrey Andreev4b450652014-02-10 06:59:54 +0200537
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