summaryrefslogtreecommitdiffstats
path: root/user_guide_src/source/libraries/encryption.rst
diff options
context:
space:
mode:
Diffstat (limited to 'user_guide_src/source/libraries/encryption.rst')
-rw-r--r--user_guide_src/source/libraries/encryption.rst585
1 files changed, 0 insertions, 585 deletions
diff --git a/user_guide_src/source/libraries/encryption.rst b/user_guide_src/source/libraries/encryption.rst
deleted file mode 100644
index b16511d4d..000000000
--- a/user_guide_src/source/libraries/encryption.rst
+++ /dev/null
@@ -1,585 +0,0 @@
-##################
-Encryption Library
-##################
-
-.. important:: DO NOT use this or any other *encryption* library for
- user password storage! Passwords must be *hashed* instead, and you
- should do that via PHP's own `Password Hashing extension
- <http://php.net/password>`_.
-
-The Encryption Library provides two-way data encryption. To do so in
-a cryptographically secure way, it utilizes PHP extensions that are
-unfortunately not always available on all systems.
-You must meet one of the following dependencies in order to use this
-library:
-
-- `OpenSSL <http://php.net/openssl>`_
-- `MCrypt <http://php.net/mcrypt>`_ (and `MCRYPT_DEV_URANDOM` availability)
-
-If neither of the above dependencies is met, we simply cannot offer
-you a good enough implementation to meet the high standards required
-for proper cryptography.
-
-.. contents::
- :local:
-
-.. raw:: html
-
- <div class="custom-index container"></div>
-
-****************************
-Using the Encryption Library
-****************************
-
-Initializing the Class
-======================
-
-Like most other classes in CodeIgniter, the Encryption library is
-initialized in your controller using the ``$this->load->library()``
-method::
-
- $this->load->library('encryption');
-
-Once loaded, the Encryption library object will be available using::
-
- $this->encryption
-
-Default behavior
-================
-
-By default, the Encryption Library will use the AES-128 cipher in CBC
-mode, using your configured *encryption_key* and SHA512 HMAC authentication.
-
-.. note:: AES-128 is chosen both because it is proven to be strong and
- because of its wide availability across different cryptographic
- software and programming languages' APIs.
-
-However, the *encryption_key* is not used as is.
-
-If you are somewhat familiar with cryptography, you should already know
-that a HMAC also requires a secret key and using the same key for both
-encryption and authentication is a bad practice.
-
-Because of that, two separate keys are derived from your already configured
-*encryption_key*: one for encryption and one for authentication. This is
-done via a technique called `HMAC-based Key Derivation Function
-<http://en.wikipedia.org/wiki/HKDF>`_ (HKDF).
-
-Setting your encryption_key
-===========================
-
-An *encryption key* is a piece of information that controls the
-cryptographic process and permits a plain-text string to be encrypted,
-and afterwards - decrypted. It is the secret "ingredient" in the whole
-process that allows you to be the only one who is able to decrypt data
-that you've decided to hide from the eyes of the public.
-After one key is used to encrypt data, that same key provides the **only**
-means to decrypt it, so not only must you chose one carefully, but you
-must not lose it or you will also lose access to the data.
-
-It must be noted that to ensure maximum security, such key *should* not
-only be as strong as possible, but also often changed. Such behavior
-however is rarely practical or possible to implement, and that is why
-CodeIgniter gives you the ability to configure a single key that is to be
-used (almost) every time.
-
-It goes without saying that you should guard your key carefully. Should
-someone gain access to your key, the data will be easily decrypted. If
-your server is not totally under your control it's impossible to ensure
-key security so you may want to think carefully before using it for
-anything that requires high security, like storing credit card numbers.
-
-Your encryption key **must** be as long as the encyption algorithm in use
-allows. For AES-128, that's 128 bits or 16 bytes (charcters) long.
-You will find a table below that shows the supported key lengths of
-different ciphers.
-
-The key should be as random as possible and it **must not** be a regular
-text string, nor the output of a hashing function, etc. In order to create
-a proper key, you must use the Encryption library's ``create_key()`` method
-::
-
- // $key will be assigned a 16-byte (128-bit) random key
- $key = $this->encryption->create_key(16);
-
-The key can be either stored in your *application/config/config.php*, or
-you can design your own storage mechanism and pass the key dynamically
-when encrypting/decrypting.
-
-To save your key to your *application/config/config.php*, open the file
-and set::
-
- $config['encryption_key'] = 'YOUR KEY';
-
-You'll notice that the ``create_key()`` method outputs binary data, which
-is hard to deal with (i.e. a copy-paste may damage it), so you may use
-``bin2hex()``, ``hex2bin()`` or Base64-encoding to work with the key in
-a more friendly manner. For example::
-
- // Get a hex-encoded representation of the key:
- $key = bin2hex($this->encryption->create_key(16));
-
- // Put the same value in your config with hex2bin(),
- // so that it is still passed as binary to the library:
- $config['encryption_key'] = hex2bin(<your hex-encoded key>);
-
-.. _ciphers-and-modes:
-
-Supported encryption ciphers and modes
-======================================
-
-.. note:: The terms 'cipher' and 'encryption algorithm' are interchangeable.
-
-Portable ciphers
-----------------
-
-Because MCrypt and OpenSSL (also called drivers throughout this document)
-each support different sets of encryption algorithms and often implement
-them in different ways, our Encryption library is designed to use them in
-a portable fashion, or in other words - it enables you to use them
-interchangeably, at least for the ciphers supported by both drivers.
-
-It is also implemented in a way that aims to match the standard
-implementations in other programming languages and libraries.
-
-Here's a list of the so called "portable" ciphers, where
-"CodeIgniter name" is the string value that you'd have to pass to the
-Encryption library to use that cipher:
-
-======================== ================== ============================ ===============================
-Cipher name CodeIgniter name Key lengths (bits / bytes) Supported modes
-======================== ================== ============================ ===============================
-AES-128 / Rijndael-128 aes-128 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB
-AES-192 aes-192 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB
-AES-256 aes-256 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB
-DES des 56 / 7 CBC, CFB, CFB8, OFB, ECB
-TripleDES tripledes 56 / 7, 112 / 14, 168 / 21 CBC, CFB, CFB8, OFB
-Blowfish blowfish 128-448 / 16-56 CBC, CFB, OFB, ECB
-CAST5 / CAST-128 cast5 88-128 / 11-16 CBC, CFB, OFB, ECB
-RC4 / ARCFour rc4 40-2048 / 5-256 Stream
-======================== ================== ============================ ===============================
-
-.. important:: Because of how MCrypt works, if you fail to provide a key
- with the appropriate length, you might end up using a different
- algorithm than the one configured, so be really careful with that!
-
-.. note:: In case it isn't clear from the above table, Blowfish, CAST5
- and RC4 support variable length keys. That is, any number in the
- shown ranges is valid, although in bit terms that only happens
- in 8-bit increments.
-
-.. note:: Even though CAST5 supports key lengths lower than 128 bits
- (16 bytes), in fact they will just be zero-padded to the
- maximum length, as specified in `RFC 2144
- <http://tools.ietf.org/rfc/rfc2144.txt>`_.
-
-.. note:: Blowfish supports key lengths as small as 32 bits (4 bytes), but
- our tests have shown that only lengths of 128 bits (16 bytes) or
- higher are properly supported by both MCrypt and OpenSSL. It is
- also a bad practice to use such low-length keys anyway.
-
-Driver-specific ciphers
------------------------
-
-As noted above, MCrypt and OpenSSL support different sets of encryption
-ciphers. For portability reasons and because we haven't tested them
-properly, we do not advise you to use the ones that are driver-specific,
-but regardless, here's a list of most of them:
-
-
-============== ========= ============================== =========================================
-Cipher name Driver Key lengths (bits / bytes) Supported modes
-============== ========= ============================== =========================================
-AES-128 OpenSSL 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
-AES-192 OpenSSL 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
-AES-256 OpenSSL 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB, XTS
-Rijndael-128 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-Rijndael-192 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-Rijndael-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-GOST MCrypt 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-Twofish MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-CAST-128 MCrypt 40-128 / 5-16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-CAST-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-Loki97 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-SaferPlus MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-Serpent MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-XTEA MCrypt 128 / 16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-RC2 MCrypt 8-1024 / 1-128 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB
-RC2 OpenSSL 8-1024 / 1-128 CBC, CFB, OFB, ECB
-Camellia-128 OpenSSL 128 / 16 CBC, CFB, CFB8, OFB, ECB
-Camellia-192 OpenSSL 192 / 24 CBC, CFB, CFB8, OFB, ECB
-Camellia-256 OpenSSL 256 / 32 CBC, CFB, CFB8, OFB, ECB
-Seed OpenSSL 128 / 16 CBC, CFB, OFB, ECB
-============== ========= ============================== =========================================
-
-.. note:: If you wish to use one of those ciphers, you'd have to pass
- its name in lower-case to the Encryption library.
-
-.. note:: You've probably noticed that all AES cipers (and Rijndael-128)
- are also listed in the portable ciphers list. This is because
- drivers support different modes for these ciphers. Also, it is
- important to note that AES-128 and Rijndael-128 are actually
- the same cipher, but **only** when used with a 128-bit key.
-
-.. note:: CAST-128 / CAST-5 is also listed in both the portable and
- driver-specific ciphers list. This is because OpenSSL's
- implementation doesn't appear to be working correctly with
- key sizes of 80 bits and lower.
-
-.. note:: RC2 is listed as supported by both MCrypt and OpenSSL.
- However, both drivers implement them differently and they
- are not portable. It is probably worth noting that we only
- found one obscure source confirming that it is MCrypt that
- is not properly implementing it.
-
-.. _encryption-modes:
-
-Encryption modes
-----------------
-
-Different modes of encryption have different characteristics and serve
-for different purposes. Some are stronger than others, some are faster
-and some offer extra features.
-We are not going in depth into that here, we'll leave that to the
-cryptography experts. The table below is to provide brief informational
-reference to our more experienced users. If you are a beginner, just
-stick to the CBC mode - it is widely accepted as strong and secure for
-general purposes.
-
-=========== ================== ================= ===================================================================================================================================================
-Mode name CodeIgniter name Driver support Additional info
-=========== ================== ================= ===================================================================================================================================================
-CBC cbc MCrypt, OpenSSL A safe default choice
-CTR ctr MCrypt, OpenSSL Considered as theoretically better than CBC, but not as widely available
-CFB cfb MCrypt, OpenSSL N/A
-CFB8 cfb8 MCrypt, OpenSSL Same as CFB, but operates in 8-bit mode (not recommended).
-OFB ofb MCrypt, OpenSSL N/A
-OFB8 ofb8 MCrypt Same as OFB, but operates in 8-bit mode (not recommended).
-ECB ecb MCrypt, OpenSSL Ignores IV (not recommended).
-XTS xts OpenSSL Usually used for encrypting random access data such as RAM or hard-disk storage.
-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.
-=========== ================== ================= ===================================================================================================================================================
-
-Message Length
-==============
-
-It's probably important for you to know that an encrypted string is usually
-longer than the original, plain-text string (depending on the cipher).
-
-This is influenced by the cipher algorithm itself, the IV prepended to the
-cipher-text and the HMAC authentication message that is also prepended.
-Furthermore, the encrypted message is also Base64-encoded so that it is safe
-for storage and transmission, regardless of a possible character set in use.
-
-Keep this information in mind when selecting your data storage mechanism.
-Cookies, for example, can only hold 4K of information.
-
-.. _configuration:
-
-Configuring the library
-=======================
-
-For usability, performance, but also historical reasons tied to our old
-:doc:`Encrypt Class <encrypt>`, the Encryption library is designed to
-use repeatedly the same driver, encryption cipher, mode and key.
-
-As noted in the "Default behavior" section above, this means using an
-auto-detected driver (OpenSSL has a higher priority), the AES-128 ciper
-in CBC mode, and your ``$config['encryption_key']`` value.
-
-If you wish to change that however, you need to use the ``initialize()``
-method. It accepts an associative array of parameters, all of which are
-optional:
-
-======== ===============================================
-Option Possible values
-======== ===============================================
-driver 'mcrypt', 'openssl'
-cipher Cipher name (see :ref:`ciphers-and-modes`)
-mode Encryption mode (see :ref:`encryption-modes`)
-key Encryption key
-======== ===============================================
-
-For example, if you were to change the encryption algorithm and
-mode to AES-256 in CTR mode, this is what you should do::
-
- $this->encryption->initialize(
- array(
- 'cipher' => 'aes-256',
- 'mode' => 'ctr',
- 'key' => '<a 32-character random string>'
- )
- );
-
-Note that we only mentioned that you want to change the ciper and mode,
-but we also included a key in the example. As previously noted, it is
-important that you choose a key with a proper size for the used algorithm.
-
-There's also the ability to change the driver, if for some reason you
-have both, but want to use MCrypt instead of OpenSSL::
-
- // Switch to the MCrypt driver
- $this->encryption->initialize(array('driver' => 'mcrypt'));
-
- // Switch back to the OpenSSL driver
- $this->encryption->initialize(array('driver' => 'openssl'));
-
-Encrypting and decrypting data
-==============================
-
-Encrypting and decrypting data with the already configured library
-settings is simple. As simple as just passing the string to the
-``encrypt()`` and/or ``decrypt()`` methods::
-
- $plain_text = 'This is a plain-text message!';
- $ciphertext = $this->encryption->encrypt($plain_text);
-
- // Outputs: This is a plain-text message!
- echo $this->encryption->decrypt($ciphertext);
-
-And that's it! The Encryption library will do everything necessary
-for the whole process to be cryptographically secure out-of-the-box.
-You don't need to worry about it.
-
-.. important:: Both methods will return FALSE in case of an error.
- While for ``encrypt()`` this can only mean incorrect
- configuration, you should always check the return value
- of ``decrypt()`` in production code.
-
-How it works
-------------
-
-If you must know how the process works, here's what happens under
-the hood:
-
-- ``$this->encryption->encrypt($plain_text)``
-
- #. Derive an encryption key and a HMAC key from your configured
- *encryption_key* via HKDF, using the SHA-512 digest algorithm.
-
- #. Generate a random initialization vector (IV).
-
- #. Encrypt the data via AES-128 in CBC mode (or another previously
- configured cipher and mode), using the above-mentioned derived
- encryption key and IV.
-
- #. Prepend said IV to the resulting cipher-text.
-
- #. Base64-encode the resulting string, so that it can be safely
- stored or transferred without worrying about character sets.
-
- #. Create a SHA-512 HMAC authentication message using the derived
- HMAC key to ensure data integrity and prepend it to the Base64
- string.
-
-- ``$this->encryption->decrypt($ciphertext)``
-
- #. Derive an encryption key and a HMAC key from your configured
- *encryption_key* via HKDF, using the SHA-512 digest algorithm.
- Because your configured *encryption_key* is the same, this
- will produce the same result as in the ``encrypt()`` method
- above - otherwise you won't be able to decrypt it.
-
- #. Check if the string is long enough, separate the HMAC out of
- it and validate if it is correct (this is done in a way that
- prevents timing attacks against it). Return FALSE if either of
- the checks fails.
-
- #. Base64-decode the string.
-
- #. Separate the IV out of the cipher-text and decrypt the said
- cipher-text using that IV and the derived encryption key.
-
-.. _custom-parameters:
-
-Using custom parameters
------------------------
-
-Let's say you have to interact with another system that is out
-of your control and uses another method to encrypt data. A
-method that will most certainly not match the above-described
-sequence and probably not use all of the steps either.
-
-The Encryption library allows you to change how its encryption
-and decryption processes work, so that you can easily tailor a
-custom solution for such situations.
-
-.. note:: It is possible to use the library in this way, without
- setting an *encryption_key* in your configuration file.
-
-All you have to do is to pass an associative array with a few
-parameters to either the ``encrypt()`` or ``decrypt()`` method.
-Here's an example::
-
- // Assume that we have $ciphertext, $key and $hmac_key
- // from on outside source
-
- $message = $this->encryption->decrypt(
- $ciphertext,
- array(
- 'cipher' => 'blowfish',
- 'mode' => 'cbc',
- 'key' => $key,
- 'hmac_digest' => 'sha256',
- 'hmac_key' => $hmac_key
- )
- );
-
-In the above example, we are decrypting a message that was encrypted
-using the Blowfish cipher in CBC mode and authenticated via a SHA-256
-HMAC.
-
-.. important:: Note that both 'key' and 'hmac_key' are used in this
- example. When using custom parameters, encryption and HMAC keys
- are not derived like the default behavior of the library is.
-
-Below is a list of the available options.
-
-However, unless you really need to and you know what you are doing,
-we advise you to not change the encryption process as this could
-impact security, so please do so with caution.
-
-============= =============== ============================= ======================================================
-Option Default value Mandatory / Optional Description
-============= =============== ============================= ======================================================
-cipher N/A Yes Encryption algorithm (see :ref:`ciphers-and-modes`).
-mode N/A Yes Encryption mode (see :ref:`encryption-modes`).
-key N/A Yes Encryption key.
-hmac TRUE No Whether to use a HMAC.
- Boolean. If set to FALSE, then *hmac_digest* and
- *hmac_key* will be ignored.
-hmac_digest sha512 No HMAC message digest algorithm (see :ref:`digests`).
-hmac_key N/A Yes, unless *hmac* is FALSE HMAC key.
-raw_data FALSE No Whether the cipher-text should be raw.
- Boolean. If set to TRUE, then Base64 encoding and
- decoding will not be performed and HMAC will not
- be a hexadecimal string.
-============= =============== ============================= ======================================================
-
-.. important:: ``encrypt()`` and ``decrypt()`` will return FALSE if
- a mandatory parameter is not provided or if a provided
- value is incorrect. This includes *hmac_key*, unless *hmac*
- is set to FALSE.
-
-.. _digests:
-
-Supported HMAC authentication algorithms
-----------------------------------------
-
-For HMAC message authentication, the Encryption library supports
-usage of the SHA-2 family of algorithms:
-
-=========== ==================== ============================
-Algorithm Raw length (bytes) Hex-encoded length (bytes)
-=========== ==================== ============================
-sha512 64 128
-sha384 48 96
-sha256 32 64
-sha224 28 56
-=========== ==================== ============================
-
-The reason for not including other popular algorithms, such as
-MD5 or SHA1 is that they are no longer considered secure enough
-and as such, we don't want to encourage their usage.
-If you absolutely need to use them, it is easy to do so via PHP's
-native `hash_hmac() <http://php.net/manual/en/function.hash-hmac.php>`_ function.
-
-Stronger algorithms of course will be added in the future as they
-appear and become widely available.
-
-***************
-Class Reference
-***************
-
-.. php:class:: CI_Encryption
-
- .. php:method:: initialize($params)
-
- :param array $params: Configuration parameters
- :returns: CI_Encryption instance (method chaining)
- :rtype: CI_Encryption
-
- Initializes (configures) the library to use a different
- driver, cipher, mode or key.
-
- Example::
-
- $this->encryption->initialize(
- array('mode' => 'ctr')
- );
-
- Please refer to the :ref:`configuration` section for detailed info.
-
- .. php:method:: encrypt($data[, $params = NULL])
-
- :param string $data: Data to encrypt
- :param array $params: Optional parameters
- :returns: Encrypted data or FALSE on failure
- :rtype: string
-
- Encrypts the input data and returns its ciphertext.
-
- Example::
-
- $ciphertext = $this->encryption->encrypt('My secret message');
-
- Please refer to the :ref:`custom-parameters` section for information
- on the optional parameters.
-
- .. php:method:: decrypt($data[, $params = NULL])
-
- :param string $data: Data to decrypt
- :param array $params: Optional parameters
- :returns: Decrypted data or FALSE on failure
- :rtype: string
-
- Decrypts the input data and returns it in plain-text.
-
- Example::
-
- echo $this->encryption->decrypt($ciphertext);
-
- Please refer to the :ref:`custom-parameters` secrion for information
- on the optional parameters.
-
- .. php:method:: create_key($length)
-
- :param int $length: Output length
- :returns: A pseudo-random cryptographic key with the specified length, or FALSE on failure
- :rtype: string
-
- Creates a cryptographic key by fetching random data from
- the operating system's sources (i.e. /dev/urandom).
-
- .. php:method:: hkdf($key[, $digest = 'sha512'[, $salt = NULL[, $length = NULL[, $info = '']]]])
-
- :param string $key: Input key material
- :param string $digest: A SHA-2 family digest algorithm
- :param string $salt: Optional salt
- :param int $length: Optional output length
- :param string $info: Optional context/application-specific info
- :returns: A pseudo-random key or FALSE on failure
- :rtype: string
-
- Derives a key from another, presumably weaker key.
-
- This method is used internally to derive an encryption and HMAC key
- from your configured *encryption_key*.
-
- It is publicly available due to its otherwise general purpose. It is
- described in `RFC 5869 <https://tools.ietf.org/rfc/rfc5869.txt>`_.
-
- However, as opposed to the description in RFC 5869, this implementation
- doesn't support SHA1.
-
- Example::
-
- $hmac_key = $this->encryption->hkdf(
- $key,
- 'sha512',
- NULL,
- NULL,
- 'authentication'
- );
-
- // $hmac_key is a pseudo-random key with a length of 64 bytes \ No newline at end of file