It is a little-known fact among members of the general PHP community that the mcrypt extension, the core of most PHP-based encryption considered secure, is anything but secure. One of the biggest issues, from a security perspective, is that the mcrypt extension requires advanced knowledge of cryptography to successfully operate, which few programmers have. This leads to gross misuse and ultimately problems such as a 1 in 256 chance of data corruption. Not good odds. Furthermore, developer support for libmcrypt, the core library upon which the mcrypt extension is based, was abandoned in 2007, which means the code base is out-of-date, bug-ridden, and has no mechanism to apply patches. Accordingly, it is extremely important to understand how to perform strong encryption/decryption without using mcrypt!
openssl. This extension is well maintained, and has modern and very strong encryption/decryption capabilities.openssl_get_cipher_methods() command. Examples will include algorithms based on Advanced Encryption Standard (AES), BlowFish (BF), CAMELLIA, CAST5, Data Encryption Standard (DES), Rivest Cipher (RC) (also affectionately known as Ron's Code), and SEED. You will note that this method shows cipher methods duplicated in upper and lowercase.|
Method |
Published |
Key size (bits) |
Key block size (bytes) |
Notes |
|---|---|---|---|---|
|
|
2000 |
128, 192, 256 |
16 |
Developed by Mitsubishi and NTT |
|
|
1998 |
128, 192, 256 |
16 |
Developed by Joan Daemen and Vincent Rijmen. Originally submitted as Rijndael |
|
|
1998 |
128 |
16 |
Developed by the Korea Information Security Agency |
|
|
1996 |
40 to 128 |
8 |
Developed by Carlisle Adams and Stafford Tavares |
|
|
1993 |
1 to 448 |
8 |
Designed by Bruce Schneier |
|
|
1987 |
8 to 1,024 defaults to 64 |
8 |
Designed by Ron Rivest (one of the core founders of RSA) |
|
|
1977 |
56 (+8 parity bits) |
8 |
Developed by IBM, based on work done by Horst Feistel |
random_bytes() (new in PHP 7), which returns a true CSPRNG sequence of bytes. The length of the IV varies considerably. Try a size of 16 to start with. If a warning is generated, the correct number of bytes to be supplied for that algorithm will be shown, so adjust the size accordingly:$iv = random_bytes(16);
openssl_encrypt(). Here are the parameters that should be passed:$plainText = 'Super Secret Credentials'; $key = random_bytes(16); $method = 'aes-256-xts'; $cipherText = openssl_encrypt($plainText, $method, $key, 0, $iv);
$key and $iv, along with the openssl_decrypt() function:$plainText = openssl_decrypt($cipherText, $method, $key, 0, $iv);
In order to see which cipher methods are available, create a PHP script called chap_12_openssl_encryption.php and run this command:
<?php
echo implode(', ', openssl_get_cipher_methods());The output should look something like this:

Next, you can add values for the plain text to be encrypted, the method, key, and IV. As an example, try AES, with a key size of 256, using the XTS operating mode:
$plainText = 'Super Secret Credentials'; $method = 'aes-256-xts'; $key = random_bytes(16); $iv = random_bytes(16);
To encrypt, you can use openssl_encrypt(), specifying the parameters configured previously:
$cipherText = openssl_encrypt($plainText, $method, $key, 0, $iv);
You might also want to base 64-encode the result to make it more usable:
$cipherText = base64_encode($cipherText);
To decrypt, use the same $key and $iv values. Don't forget to un-encode the base 64 value first:
$plainText = openssl_decrypt(base64_decode($cipherText), $method, $key, 0, $iv);
Here is the output showing the base 64-encoded cipher text, followed by the decrypted plain text:

If you supply an incorrect number of bytes for the IV, for the cipher method chosen, a warning message will be shown:

In PHP 7, there was a problem when using open_ssl_encrypt() and open_ssl_decrypt() and the
Authenticated Encrypt with Associated Data (AEAD) modes supported: GCM and CCM. Accordingly, in PHP 7.1, three extra parameters have been added to these functions, as follows:
For more information, you can refer to https://wiki.php.net/rfc/openssl_aead.
For an excellent discussion on why the mcrypt extension is being deprecated in PHP 7.1, please refer to the article at https://wiki.php.net/rfc/mcrypt-viking-funeral. For a good description of block cipher, which forms the basis for the various cipher methods, refer to the article present at https://en.wikipedia.org/wiki/Block_cipher. For an excellent description of AES, refer to https://en.wikipedia.org/wiki/Advanced_Encryption_Standard. A good article that describes encryption operation modes can be seen at https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation.
For some of the newer modes, if the data to be encrypted is less than the block size, openssl_decrypt() will return no value. If you pad the data to be at least the block size, the problem goes away. Most of the modes implement internal padding so this is not an issue. With some of the newer modes (that is, xts) you might see this problem. Be sure to conduct tests on short strings of data less than eight characters before putting your code into production.