Encrypting and Decrypting Within Laravel Applications

November 30, 2016 —John Koster

Laravel provides support for AES encryption, a symmetric key encryption scheme, right out of the box. Laravel also automatically signs all encrypted values with a message authentication code (MAC) so that any modifications to the encrypted data can be detected. Laravel internally accomplishes this through various methods built around PHP's hash_hmac function. SHA256 is used as the hashing function when calculating the MAC hash.

Laravel provides a very simple API for interacting with the encryption services. It defines a Illuminate\Contracts\Encryption\Encrypter interface, which all encryption classes must implement. The Encrypter interface defines two methods[^supportedStaticMethod] that be implemented: encrypt($value), which is used to encrypt a value and decrypt($payload), which is used to decrypt a previously encrypted value.

[^supportedStaticMethod]: All of the default implementations of Encrypter also define a public static method supported($key, $cipher) which is used by the Illuminate\Encryption\EncryptionServiceProvider to determine if the Encrypter implementation supports the $key and $cipher configured for the current application (either in the config/app.php configuration file, or though the .env file).

There are two implementations of Encrypter shipped with Laravel. The first one is the Illuminate\Encryption\Encrypter implementation, which uses OpenSSL to perform the encryption and decryption. Laravel attempts to use this implementation first. If the key and cipher are not supported by this implementation Laravel then checks to see if the key and cipher are supported by Illuminate\Encryption\McryptEncrypter, which uses the PHP mcrypt extension to perform the encryption and decryption operations.

#Configuring Encryption

The key and cipher for encryption must be set and configured. The cipher is set in the config/app.php configuration file by changing the value of cipher. The following table lists the supported ciphers and the Encrypter (all Encrypter implementations are relative to the Illuminate\Encryption\ namespace) implementation that will handle them, and the order that they are checked:

Cipher Encrypter Implementation
AES-128-CBC Encrypter
AES-256-CBC Encrypter
MCRYPT_RIJNDAEL_128 McryptEncrypter
MCRYPT_RIJNDAEL_256 McryptEncrypter

An encryption key must also be configured. Typically this is done by running the following artisan command:

1php artisan key:generate

The key:generate command will update the application's environment file with the key that is generated during command execution. Encryption keys must be a random, thirty-two character long string. Encryption keys are stored in base 64 encoding for easier storage and retrieval.

It is important to note that if the encryption key needs to be regenerated after an application has been in use, any data that was previously encrypted using the old key cannot be decrypted using the new encryption key. While regenerating the encryption key is not recommended, there are some scenarios where it is beneficial, if not absolutely critical to do so.

When these scenarios arise, the problems can be overcome by decrypting the old data and reapplying the encryption using the new encryption key.

#Encrypting and Decrypting Data

As stated earlier, encryption of data is accomplished by calling the encrypt($$value) method on an Encrypter implementation and decryption of data is accomplished by calling the decrypt($payload) on an Encrypter implementation. The following code examples will assume the that the cipher was:

1AES-256-CBC

and encryption (application) key was the following:

1r3x4NIxNOsWLJFK2opKqA0q9YEWt9y69

It is not recommended to use the encryption key that is used in this article. Any messages encrypted with the provided key can also be decrypted with the provided key. This key should be used for example purposes only, and should be assumed insecure.

The following code example will encrypt and decrypt the string Hello, Universe:

1<?php
2 
3// Get an Encrypter implementation from
4// the service container.
5$encrypter = app('Illuminate\Contracts\Encryption\Encrypter');
6 
7// Encrypt the string `Hello, Universe`
8$encrypted = $encrypter->encrypt('Hello, Universe');

After the above code has executed, the $encrypted value would be a string and contain a value similar to the following output (the actual output will change each time the code is ran):

1eyJpdiI6ImhNZTN3eEVFTXFsYVBSN3NPNTlRbnc9PSIsInZhbHVlIjoiZ3FOYTV5SmdlUnZ0UHlrbXdxU3NoRDllKzdGTXlTakdEOG9tTHpEMVRJRT0iLCJtYWMiOiJmOWVhZDkzY2NhMTdjMzQzNDE0MTM0MDBlNTFmZGUwMmQ0MGRkYWYxNzFhZTc5ODI1ZWJlNjIxYzk0MzM2YWFkIn0=

It is very easy to decrypt the encrypted message using the decrypt method:

1<?php
2 
3// A hard-coded encrypted value.
4$encryptedValue = 'eyJpdiI6ImhNZTN3eEVFTXFsYVBSN3NPNTlRb'.
5 'nc9PSIsInZhbHVlIjoiZ3FOYTV5SmdlUnZ0UH'.
6 'lrbXdxU3NoRDllKzdGTXlTakdEOG9tTHpEMVR'.
7 'JRT0iLCJtYWMiOiJmOWVhZDkzY2NhMTdjMzQz'.
8 'NDE0MTM0MDBlNTFmZGUwMmQ0MGRkYWYxNzFhZ'.
9 'Tc5ODI1ZWJlNjIxYzk0MzM2YWFkIn0=';
10 
11// Decrypt the $encrypted variable.
12$decryptedDynamic = $encrypter->decrypt($encrypted);
13 
14// Decrypt the hard-coded encrypted value.
15$decryptedHardCoded = $encrypter->decrypt($encryptedValue);

After the above code has ran, the $decryptedDynamic and $decryptedHardCoded variables would both be strings and contain the value Hello, Universe.

#The Crypt Facade

Laravel provides many facades to make it easier to quickly build application and test ideas. One such facade is the Illuminate\Support\Facades\Crypt facade, which provides access to whatever implementation is bound to the Illuminate\Contracts\Encryption\Encrypter interface within the service container. The following code example demonstrates the basic usage of the Crypt facade:

1<?php
2 
3use Illuminate\Support\Facades\Crypt;
4 
5// Encrypt the message 'Hello, Universe'.
6$encrypted = Crypt::encrypt('Hello, Universe');
7 
8 
9// Decrypt the $encrypted message.
10$message = Crypt::decrypt($encrypted);

Some absolutely amazing
people

The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.