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