on 19 March 19
Many applications have a database at their core, and very often, this database is the mature and popular MySQL. Often it is the most sensitive information that gets stored in the database: customer details, credit card numbers, passwords (or password hashes) and so on. MySQL encryption is an industry best practice.
MySQL Encryption: Why?
Obviously, the sensitive information within the database is enough motivation for secure MySQL Encryption.
Often there are also requirements by regulatory bodies to encrypt the database-resident data, either applying to the entire database or to selected tables or columns.
There is often another motivation to encrypt some of the data: segregation between users, between applications, and most often between administrative users such as the Database Administrator and the business data. Without encryption, the DBA can read any of the data stored in the database. With encryption, provided it happens at the right layer, you can protect the most sensitive data, while keeping most of the data unencrypted and so more accessible to applications and utility tools.
MySQL Encryption: How?
Until recently, you typically needed to set up your own MySQL instance on a server, and manage the database yourself. The organization would have to deal with scaling, replication, backups and disaster recovery. Many organizations ended up employing a full time person to continuously care for the database.
In the last few years, cloud-based databases have become increasingly popular. The most prominent one is Amazon Web Services' RDS, a service that supports several database technologies, including MySQL. It should be noted that RDS and other cloud databases do not in general provide encryption out of the box. Some of the techniques described below also apply to cloud databases, with the important exception of full-disk encryption.
MySQL Encryption: Available Options
The simplest way to encrypt a database is to overlay it on a fully-encrypted disk. There are many solutions available for full-disk encryption (FDE). Two examples are the Linux open-source dm-crypt, and the more user-friendly Porticor Virtual Private Data, which bundles up-in-minutes full disk encryption together with an innovative and highly secure key management service.
Once you have the encrypted disk, it is an easy matter to configure the database so that the data directory resides on that disk. Now, assuming you manage your encryption keys correctly, if you ever lose your disk, you do not need to worry about your sensitive data being exposed to prying eyes. This addresses some of the threats facing your data, but clearly not all of them. For example, someone who breaks into the application or someone who obtains administrative privileges on the database would still be able to read the data, even though it is fully encrypted.
So let us look at encryption at a higher layer. The next layer up from the disk would be the RDBMS (database engine) itself. Unlike other databases, MySQL unfortunately does not provide a Transparent Data Encryption (TDE) solution. Which means we need to go still higher.
MySQL does offer encryption functions that are available to SQL code run from the application, as well as to stored procedures. Please refer to the MySQL documentation for details. You can use these functions to encrypt specific database tables, columns or even individual fields. Just like for disk encryption, it is best to have a key management solution available, so that you don't need to rely on easy to guess passwords or end up storing your encryption keys along with the data. Once you have a cryptographic key from your key management solution, you can use it in the following SQL statement:
UPDATE T1 SET T1.f = AES_ENCRYPT(value, encryption_key) WHERE ...
This will encrypt the value before it is saved into the database. To retrieve the original value you can use AES_DECRYPT to decrypt stored value, as part of a SELECT statement.
There are different ways to wrap this functionality so that code changes are minimized. One alternative is to create a database view that performs decryption of data on the fly, which eliminates the need to change all relevant SELECT statements. The security cost is high though: the encryption key would need to be specified during the view definition and so would be available to all database users with the appropriate privileges. That is, no more protection from a rogue DBA.
You should note that when using the native MySQL encryption functions, the sensitive data is still sent to the database, even if it is never stored. If you want to protect against an active attacker on the database, your best bet is application-level encryption. Essentially all programming languages are nowadays available with decent encryption facilities. Examples include the Java SealedObject class and .NET Cryptographic Services). This may be more onerous than using the MySQL built-ins, but the upside is that you can get better security by using cipher-block chaining (a.k.a. CBC mode) than you'd get with the MySQL native ECB mode.
MySQL Encryption: An Important Layer of Security
To summarize, database encryption provides an important layer of security to your sensitive data. There are different ways to encrypt the data, all very practical. But remember that even the best crypto library will not secure your data unless you are using a secure key management infrastructure