Themis provides several methods for encrypting data at rest - Secure Cell, Secure Message. Where do people store data? In files and in databases. Sometimes, you want to manipulate cryptographic data on the database side, this is where Themis plugins come handy.
Even though generally it's a questionable practice, but sometimes you need to encrypt/decrypt data on the database side. Moreover, there are some security designs where you have to:
- you want to offload computation to a more able server.
- you want to minimize exposure of cryptographically-sensitive material in the app which passes through the key (via messaging or keyboard input from the user).
- you don't plan to actually use decrypted outside database server - you plan to decrypt something, use it within this query / stored procedure and just return not-so-sensitive output to the user.
- you trust database server more than application server (for example, your application runs in the browser and just talks to database over JSON over the unprotected channel).
It's all about having a choice and using it wisely.
We're releasing two plugins (Redis and PostgreSQL) to encrypt/decrypt your data on database server side via native modules. They're Apache 2, built on Linux and for Linux. Trying to build elsewhere? You can report your successes and failures in issues of corresponding repositories and we'll try to help or praise you!
Let's talk a bit about what these Themis plugins let you do.
Secure Cell is simple - give our function your data and your key (optionally, supply context as well), we will encrypt it with AES in either GCM (preferrable, default mode in database plugins) or CTR (optional, not available in database plugins yet). Secure Cell provides best practices in symmetric encryption, aiming at highest possible security guarantees.
Secure Message allows one party to "send" data to the other - e.g., encrypt the data with sender's private and receiver's public key. This way, sender's public key and receiver's private is required to decrypt the envelope. What we do in Themis plugin is we "send" the data from nowhere - generate a random keypair, encrypt data with a private key and supplied public key, attach a public key to the encrypted record, so that anyone with receiver's private key (matching public one) will be able to decrypt it.
RD_Themis: Redis version
RD_Themis is a plugin for Redis database and is available here, with docs, examples and building instructions.
Syntax is extremely simple:
rd_themis.cset key password data rd_themis.cget key password
rd_themis.msset key public_key data rd_themis.msget key private_key
PG_Themis: PostgreSQL version
PG_Themis is a plugin for PostgreSQL and is available here along with building instructions and examples.
Syntax is, as follows:
-- Encrypts data with key. CREATE FUNCTION pg_themis_scell_encrypt_seal(data bytea, key bytea) RETURNS bytea AS 'pg_themis', 'pg_themis_scell_encrypt_seal' LANGUAGE c STRICT; -- Decrypts data with key. CREATE FUNCTION pg_themis_scell_decrypt_seal(encrypted_data bytea, key bytea) RETURNS bytea AS 'pg_themis', 'pg_themis_scell_decrypt_seal' LANGUAGE c STRICT;
-- Encrypts data with public key. CREATE FUNCTION pg_themis_smessage_encrypt(plain_data bytea, public_key bytea) RETURNS bytea AS 'pg_themis', 'pg_themis_smessage_encrypt' LANGUAGE c STRICT; -- Decrypts data with private_key. CREATE FUNCTION pg_themis_smessage_decrypt(encrypted_data bytea, private_key bytea) RETURNS bytea AS 'pg_themis', 'pg_themis_smessage_decrypt' LANGUAGE c STRICT;
Use-cases and ideas
Basically, there are a few cases where you need to run encryption on the database side.
Decrypting on untrusted attack surface
There are systems, which have more chances to get attacked, risky to a point, where you don't want to perform sensitive operations there. But you can safely perform database access via trusted or semi-trusted channel. This is where Themis in your database comes handy.
Front-end apps unable to have trusted code execution
As an example of the above, a web app, talking to Redis via HTTP API, is unable to run cryptography, yet able to hand password securely to a server to encrypt/decrypt the data.
Cryptography is quite expensive. If you're running extremely speedy HTTP balancer, handling millions of connections and saving every page of memory / every CPU cycle, decrypting keys might not be a good idea. If a connection between HA infrastructure and database is trusted and they've exchanged secrets previously properly, why not decrypt on DB side and return clear data to performance-critical node? Moreover, you might be in a less appealing situation: you might run web stack which isn't handling loads well, not being able to scale it out elastically and want to make sure that nothing in code's execution chain blocks for too long. This is also a typical reason to offload decryption to the backend.
Living without secrets
You can actually use secrets that are stored on database side - and use something to authenticate queries that both pull these secrets from the database and invoke Themis functions for encrypting / decrypting. It's extremely risky (holding keys and data nearby is a bad habit), but in some architectures, where it is the least risky point of storage, such idea is justified. Just don't call them secrets anymore :)
Database as exchange bus
Since databases are frequently used as a shared state in stateless services, ability to connect strong clients (clients able to run proper Themis version) with clients, which are at least able to perform crypto on DB part, allows building an exchange of sensitive data in a heterogenous environment.
In a pursuit to make Acra and Hermes available on numerous platforms, we'll be porting Themis to many more database systems, and might even expand its feature set a bit in the next releases with database-friendly features. Stay tuned for more!