Getting started: If this is the first module you’ve used on the site that requires the Encrypt module, the first thing you’ll need to do is install and configure that module and its dependencies.
Take a look at this post for How to Setup Encrypt Module for Drupal 8, then come back here to continue setting up the Field Encrypt module. I’ll wait.
Welcome back! Now let’s setup the Field Encrypt module!
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.
Adds options to encrypt field values. The goal of this module is to create a method for encrypting field values when stored in the database.
The Field Encryption module provides a UI for managing the encryption settings for fields within Drupal. After enabling the module, you can edit the Storage Settings on a field and configure the field to encrypt its data within the database, along with some other settings.
Field Encrypt: Automatically encrypt field data at rest
Now that all the pieces are in place, we can start configuring our fields to encrypt their data within the database.
There are two general areas of configuration with the Field Encrypt module. First is the site-wide default settings. To view these settings navigate to Configuration > System > Field Encrypt Settings (
Here you can configure which properties of a field type are checked by default when enabling field encryption. For example, if you have the Address field installed on your site and know that every time you choose to encrypt an Address field you want the the address_line1 and postal_code properties to be encrypted, you can set those here as the default.
Basically, this settings page is just to give you the administrator some common encryption defaults between field types. Changing the settings here does not affect any of your existing fields. You don’t necessarily need to modify these settings at all.
Next up, let’s configure a field to make it encrypt its data!
For the sake of example, let’s add a new field to the Basic Page content type and setup that field to be encrypted. This will be a simple text field. After we configure the field and create some data, we’ll look at the database to see how the data is stored.
- Navigate to Structure > Content Types > Basic Page > Manage Fields (
/admin/structure/types/manage/page/fields) and click “Add Field”
- Field Type: choose “Text (plain)”
- Field Name: “Super Cool Encrypted Field”, or another name of your choosing.
- Click “Save and Continue”
- On the next page, beneath the normal Field Storage options, you should see a new checkbox labeled “Encrypt Field”. Check that box and the form will expand with some options.
- Properties: check “Text value” – Here we’re choosing which parts of the field data will be encrypted. Since this is a plain text field, there is only one property available to encrypt.
- Encryption Profile: choose “Field Encryption AES Profile” – or whatever you named the encryption profile in the previous setup.
- Uncacheable: Check this. This will make sure your unencrypted data will not be exposed in the cache, but will have a negative impact on your performance. Whether or not you want encrypted data to be cacheable in your actual usage of the module is up to you, but there are trade-offs in both cases. “Uncacheable” is the more secure option, but has a performance cost.
- Click “Save Field Settings”
And we’re done! You should now have a field that encrypts its data on saving to the database, and decrypts the data when shown to a site user. ?
Testing & Exploring the data
Let’s test this out and see what is happening behind the scenes to our data.
Create a new Basic Page and provide some text to our newly encrypted field. Everything should appear normal to you. The field data is shown decrypted when viewing or editing the node.
Screenshot: All is normal
But if we were to look at our new field in the database we will not find the data. Instead, the value of the field in the database is literally “[ENCRYPTED]”.
This is because encrypted data for fields is now stored in a few new database tables provided by the field_encrypt module.
There it is, my encrypted data.
Now to complete the circle on testing this and understanding how all these pieces fit together, I should be able to copy the encrypted data from the database, and Test Decrypt it with my Encryption Profile.
Screenshot of decrypting data taken from the database
And viola! Works like a charm.
So there we have it, we are now encrypting field data at rest using a few modules that provide simple administrative UIs and are designed to work together.
Additional Notes and Gotcha’s
As mentioned in a previous section, when you create an encryption profile with the Encrypt module, that profile becomes available to a global encryption service within your code. Though you may never need to manage your own encryption/decryption in code, let’s take a quick look at that for reference.
Programmatically Encrypt & Decrypt Data
Assuming you have created an encryption profile named “Field Encrypt AES” (with the machine name:
field_encrypt_aes), the following code is an example of using that profile programmatically.
Note: This example is both encrypting and decrypting right after the other. In the real world, you would do these things separately depending on the events taking place in the system.
Screenshot: Seeing is believing
Note how all you need to do is load the encryption profile by machine name, and you’re ready to en/decrypt! Easy enough!
Key: Encryption keys as a service with Lockr
As mentioned in the best practices section for the Key module, the ideal secure setup is storing your key on a server that is complete separate from your Drupal application. There are likely a few good ways to do this, but of note is the service provided by Lockr.
Lockr offers keys as a service. Meaning they will generate, store, and provide API access to your encryption keys. This not only solves the problem of storing your keys securely, but it offers an additional benefit to easily scale your encryption configuration.
Consider adding encryption to an application that is load-balanced across multiple servers. If you’re encrypting data within your application, then each server will need access to the keys used for that encryption.
How to use Lockr
- Visit https://www.lockr.io and create a new account.
- Download the Lockr module and its dependencies to your Drupal instance – https://www.drupal.org/project/lockr and install it.
- Installing with composer will automatically download the dependencies you need.
composer require drupal/lockr
- If you download the module another way, you will need to also download the lockr-client library to Drupal’s vendor directory – https://github.com/lockr/lockr-client
- Installing with composer will automatically download the dependencies you need.
- After installing Lockr, visit the module’s configuration page by navigating to Configuration > System > Lockr (
- Here you will be guided through generating a certificate on your machine, and providing your Lockr username and password.
- Once the Lockr module configuration is complete visit the Key module’s configuration page at Configuration > System > Keys and click “Add Key”
- Key Type: select “Lockr Encryption”
- Key Size: select “256”
- Key Provider: select “Lockr”
- Save your new Key
Now the only thing left to do is to modify your existing Encryption Profile (or create a new one) that uses this new Lockr Key. The rest of the Field Encryption setup is the same as above.
Screenshot of Lockr Key Configuration
Gotcha #1: Encrypting fields with existing data
It’s worth pointing out that at the time of this writing the field_encrypt module has a bug related to its use of cron to encrypt existing data. In testing this out I had cron hard-crash a few times and re-verified my setup to make sure I had everything configured correctly.
Luckily there is an issue for this in the queue with a working patch: https://www.drupal.org/node/2900641
Gotcha #2: Adding encryption to fields on custom entities
Also while experimenting with these modules I ran into a very confusing issue dealing with custom entities. If you add encryption to an existing field on a custom entity, you must clear your site cache before it will work correctly.
This really threw me for a loop when working with the modules, as all of my data appeared as “[ENCRYPTED]” on both entity display and the entity form. After determining there was a bug of some sort at play, I submitted an issue to the Field Encryption module: https://www.drupal.org/node/2918252
That’s all I have for now on data encryption at rest in Drupal 8, but I fully expect to be digging further into the modules and learning more ways to secure my site data.
If you’ve made it this far in the post let me know what you think. If you see any ways this post could be improved or have any questions about these modules, let me know and I’ll figure it out!