Disclaimer: This post was originally written as the first part to the How to Encrypt Field Data post, so some of the labels used in the screenshots specifically mention field encryption. If you’re setting up the encrypt module for use by another module, keep in mind that you can name your encryption key and encryption profiles whatever you want.
Some sites or applications retain sensitive data about users or clients that need to be stored within the database. And though you may feel great about your site’s security, the data that belongs to the website is not always accessible only within the application. For example: database backups contain a copy of all your site data- are your backups secured and encrypted?
Ideally your sensitive data is encrypted at rest within the database, and the data is stored separate from the key used to encrypt it. This post covers the installation and configuration of modules needed to encrypt field data at rest in Drupal 8.
Prefer to watch a video? Click here to jump to my video tutorial.
Goal: Encrypt fields of my choosing within Drupal, and store the encryption key separate from the data behind another layer of protection.
Prerequisites: To make best use of this article, you should be familiar with installing Drupal 8 modules and their dependencies, as well as being comfortable enough within a terminal to execute a few simple commands:
Needs: A secure symmetrical algorithm for encrypting data, a key that is used by the algorithm to encrypt and decrypt the data, and an API that modules can use to leverage the algorithm and key as needed to encrypt data.
Enter a set of encryption related modules for Drupal.
As with many Drupal tasks, to achieve this goal we’re going to need at least 4 modules: Key, Encrypt, Real AES, and Field Encrypt. Each of these modules performs one specific function that the others utilize. Let’s look at each one and how it fits into the others.
Key provides the ability to manage keys, which can be employed by other
modules. It gives site administrators the ability to define how and
where keys are stored, which allows the option of a high level of
security and allows sites to meet regulatory or compliance
In other words, the Key module gives you a simple UI within Drupal for managing your various keys for services. Some examples of services that may require a key are:
A password or API key for connecting to an external service, such as
PayPal, MailChimp, Authorize.net, UPS, an SMTP mail server, or Amazon
Web Services. A key used for encrypting data.
On its own, this module doesn’t do much at all. In addition to the Key module we’re going to need another module that makes use of the keys.
Real AES provides an encryption method plugin for the Encrypt module. This plugin offers authenticated encryption based on AES-128 CBC with a HMAC. It can also serve as a library loader for the Defuse PHP-encryption library.
The Real AES module is what I’ve chosen for the encryption method for this tutorial, but there are others available such as Sodium.
This module provides a global encryption service that can be invoked via the
The Encrypt module also provides an administrative UI within Drupal for creating reusable global services that leverage your encryption keys in conjunction with an encryption method. In other words, this module will provide an API to other modules so that they can make use of the encryption keys we’ll create with the Key module, and the chosen encryption method (Real AES).
After installation and configuration of the Key and Real AES modules, the Encrypt module allows us to create various “Encryption Profiles” that leverage the Keys and encryption methods of your choice. Once created, these profiles become available to the global encryption service the encrypt module provides. We’ll look at how to use this service more later.
Installation and Setup
To get started, the first thing we need to do is download these modules and their dependencies. Using a composer based Drupal codebase, this is as easy as executing one long command in the terminal. Doing it this way will automatically retrieve the Defuse PHP-encryption library required by the Real AES module.
composer require drupal/key drupal/real_aes drupal/encrypt drupal/field_encrypt
Alternatively if you are not setup with a composer based Drupal installation, you will need to download all the Drupal modules using the method you prefer and add the following required libraries to your site’s vendor directory.
- https://github.com/paragonie/random_compat (PHP 5.x support for random_bytes() and random_int())
After downloading all the modules and their requirements, enable them within Drupal. Now we need to configure each of these modules for use.
Key: Generating a key for use with Real AES
The first thing we need to do is generate an encryption key. The easiest way I’ve found to do this is actually according to the Sodium module documentation. In your terminal execute the following command, but change the path and filename to where you want to store your new key.
dd if=/dev/urandom bs=32 count=1 | base64 -i - > path/to/my/encrypt.key
This generates a 256-bit key that is base64 encoded and saves it as the file indicated in the command. I prefer the base64 encoded approach, as it allows me to easily copy and paste the key.
Best Practice: Though the Key module allows us to store the key within the site’s configuration (database), this is not ideal. Storing your encryption key within your database is like duct taping your house key to your front door. Yes, the door is technically locked, but it’s hardly secure. Instead, we want to store the key somewhere away from the data it is encrypting. Ideally on a different server entirely (more on this later), but at a bare minimum as a file outside the web-root.
Now that we have a key generated, let’s add it to the Key module within Drupal.
- Navigate to Configuration > System > Keys (
/admin/config/system/keys) and click “Add Key”
- Provide your new key with Name and Description that identifies what the key is used for. In my case, I’ve named my key “Field Encryption” and given it the description of “Used to encrypt field data”.
- Key Type: choose “Encryption”. This will change the form and provide a new field named “Key Size”.
- Key Size: select “256”
- Key Provider: choose “File”.
- File Location: provide the absolute path to the key you generated above. ie,
- Check Base64-Encoded so the module knows this key is encoded.
- Save your new Key.
If the form saves without error, then you’re done setting up the Key module 🙌. If you receive an error about the key being an incorrect size, it is likely due to the method in which you generated the key. Try generating your key again using the command mentioned above.
Encrypt: Creating a reusable Encryption profile
Since the Real AES module only provides an encryption method to Drupal, there is no additional setup required for that module and we can move on to configuring the Encrypt module.
Now we need to create an encryption profile that uses our new Key and the Real AES encryption method. Once we do so, that encryption profile becomes available for use by other modules, and also as a service within your code.
- Navigate to Configuration > System > Encryption profiles (
/admin/config/system/encryption/profiles) and click “Add Encryption Profile”
- Create a label for your new encryption profile such as “Field Encryption AES Profile”. Any name will do that allows you to reliably identify this profile.
- Encryption Method: choose “Authenticated AES (Real AES)”, and this will reload part of the form, allowing you to select a Key.
- Encryption Key: choose the Key you created in the previous section.
- Save your new Encryption Profile.
Once saved you will be redirected to the list of your encryption profiles. Before we go further, let’s test this out.
- Next to your encryption profile, choose the operation “Test”.
- On the next page, provide some random text to the “Text to encrypt” field and click “Encrypt”. In the “Encrypted text” field you should see a long random string of characters. This is your text encrypted.
- Copy the encrypted text and paste it into the “Text to decrypt” field, then click “Decrypt”.
- Now you should see your original text in the “Decrypted text” field.
If your original text is the same as your decrypted text, then both your Key and Encryption Profile are setup correctly and ready to be used.
Now you’re ready to begin encrypting data at rest within the Drupal database!