Secure Encryption with Libsodium and Acquia Cloud
Encryption is an important part of any website that needs to store sensitive information. Encryption takes sensitive data that is in a readable form and encodes it, making it unreadable. This essentially hides the information from anyone who might try to access it without permission to do so. The encoded information can only be decoded by an entity that has a paired decryption key.
Our requirements for this particular Drupal website build included:
- Acquia Cloud - One of the leading Drupal hosting providers.
- Libsodium - Because of Acquia Cloud, we needed a custom compiled php extension
- Encrypt - A Drupal module that exposes encryption APIs to other modules.
- Key and Lockr.io - Drupal modules for managing the encryption key.
- Sodium - A Drupal module to provide libsodium to the encrypt module.
Why use libsodium instead of mcrypt?
Libsodium is a portable, cross-platform implementation of NaCl. Experts recommend libsodium for its simple interface and strong cryptography. The sodium Drupal module takes an easier approach, which is to use a high-level package, paragonie/halite, to work with libsodium.
The other choice for encryption in PHP is mcrypt. It's the default method in the Drupal 7 version of the encrypt module. Despite that, it's a bad choice because it's difficult to use correctly. Mcrypt is deprecated in PHP 7.1 and removed in PHP 7.2.
Installing Libsodium on Acquia's PHP 7.1
PHP 7.2 has libsodium built in and if you're on 7.1 or below you can install it from PECL. We're going to be using Acquia Cloud, so we can't yet run PHP 7.2 and we can't install any PHP extension we want - not as easily as we'd like to.
Acquia requires that extensions be compiled including their dependencies. The php-libsodium extension depends on libsodium itself and we have to produce one binary for both libraries. We'll be compiling libsodium the crypto library as a static library and php-libsodium the php extension that provides bindings to libsodium for PHP applications as a dynamically linked library so it can be loaded by a regular PHP install.
Let's get started!
- Download the latest libsodium from https://github.com/jedisct1/libsodium/releases.
- Compile libsodium so it's static, not shared. Put it in a directory we'll use later.
$ ./configure --libdir=/home/me/sodium/library --disable-shared --enable-static--enable-static makes it static, not shared. It'll be a part of the php extension when we build it instead of a separate dependency.
--disable-shared prevents creating a shared library version of the library.
--libdir puts it in a directory where we'll use it later.
- Compile with PIC (Position Independent Code).
$ make CFLAGS='-g -O2 -fPIC'Here's our sodium library and a pkgconfig directory we'll need to point the php extension at.
$ sudo make install
$ ls /home/me/sodium/library
libsodium.a libsodium.la pkgconfig
- Download the latest version 1 release of the libsodium php extension from https://github.com/jedisct1/libsodium-php/releases.
Use phpize to get the extension ready to compile. Normally a PHP extension is compiled as part of PHP. This script is used to set up things up so it's like we're doing that. You need the -dev version of PHP to get phpize, so install php7.1-dev or the equivalent for your situation.
$ phpize7.1Now you'd notice a lot more files in the directory, like the configure script.
PHP Api Version: 20160303
Zend Module Api No: 20160303
- Set the package config directory to the one where we installed libsodium.
$ export PKG_CONFIG_DIR=/home/me/sodium/library/pkgconfig
- Configure libsodium-php with the path to libsodium.
$ ./configure --with-libsodium=/home/me/sodium/library --libdir=/home/me/sodium/library--with-libsodium tells it where to find the dependency we just created.
- Check that libsodium.so is not looking for a shared libsodium library.
$ ldd modules/libsodium.soThere's no libsodium dependency there, so we're good to use our libsodium.so PHP extension! Deploy the file and configure PHP to load the extension. Since we're on Acquia Cloud, Acquia does that after we provide the file.
linux-vdso.so.1 => (0x00007ffcdd68e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f71f26eb000)