2

I have a linux server.

I want to encrypt (and decrypt) data that is stored in a database. There are several processes that need to be able to do this, some of them my own applications, but also scripts running under nginx.

I want to use a Data Encryption Key (DEK) to do so. In order to unlock the DEK I use a Key Encryption Key (KEK). The KEK is provided by prompting the administrator when the system boots.

What is the best way of storing the DEK so that these processes (but only these!) have access to it?

My initial idea was to store it in shared memory, but that means every process has potential access to it. (is that correct?)

The next idea was to store it on a tmpfs, which at least has some access control (with regards to UIDs and GIDs) on which process can and cannot read it.

1

Misconceptions regarding the KEK and DEK

The KEK is not meant to be stored, only the eDEK (encrypted DEK) is. The KEK is input once, and is used to decrypt the eDEK. The DEK is then kept in memory by whatever process requires it, as it is fundamentally necessary for a key to be present in memory in order to be used for decryption. The KEK should be kept in memory only long enough to decrypt the eDEK, then it should be overwritten (to prevent it from lingering in freed memory). As managing keys in memory can be difficult, with many ways to screw things up badly, I strongly recommend using existing software designed for this purpose. If you do not know how and why you should lock memory that will be holding key material, or how to ensure that memset calls will not be optimized out when wiping key material from memory, you should not be implementing cryptosystems yourself. Use an existing solution, or at the very least a suitable high-end and easy-to-use crypto library.

Shared memory

Regarding your statement on shared memory, that depends on what you mean by shared memory. POSIX shared memory (shmem) is a method of storing objects in memory that any process with the proper permissions can access. It is similar to your idea of storing data in tmpfs, except POSIX shared memory uses a special API for accessing objects. In that case, storing something sensitive for a given user in shared memory may not be a great idea.

The other definition of shared memory is memory present in the address space of more than one process. A process must choose to share a given region of memory with another process, passing the MAP_SHARED flag to mmap when requesting memory from the kernel. Usually this is done by a parent process which then forks into two processes which share a specific region of memory. In this case, memory is only shared by processes which explicitly permit it.

Threat modeling

It is necessary to define your threat model. Who are you protecting this data from? Where are they positioned in relation to the data? What level of access do they have? Generally, an operating system will already provide software-level access controls, making encryption the wrong tool for preventing a malicious process from accessing data that is being used elsewhere. Encrypted storage is designed to provide data-at-rest security, protecting the data on the hard drive, should it be stolen or otherwise fall into the wrong hands. For this threat model where encryption is meant to be used, you do not need to give the key to any more processes than are needed to actually read the database. Specifically, you should let the database software do the encryption and decryption, allowing anyone with permission to connect to the database server the ability to read the contents, subject to software-level permissions.

  • Yes, I intend to use the database to do the encryption & decryption. The relevant processes that have an (in memory) DEK would use this for that purpose. I hear what you say about the KEK that should only be kept in memory long enough to decrypt the eDEKs. But those processes that use the data in its unencrypted form (and hence they need the DEK) are (re-) started regularly. The nginx scripts for instance would need this DEK 'on-the-fly'. How would they be able to if the KEK does not exist anymore? The encrypted data is held in MySQL (local). – Lieuwe Feb 8 '18 at 15:23
  • They do not need to have the DEK. They should query the database, which should do the decryption for them. The nginx script will never access the raw database data (it can't, anyway). It has to query the database. – forest Feb 9 '18 at 1:41
  • So how does MySQL get the DEK that methods like AES_ENCRYPT() and AES_DECRYPT() need? – Lieuwe Feb 9 '18 at 9:43
  • 1
    Ok, so rather than storing the KEK in some volatile space, I keep the DEK in memory or perhaps tmpfs. That brings me back to the same core issue. How do I best control access to that DEK. – Lieuwe Feb 9 '18 at 14:35
  • 1
    @Lieuwe The DEK should be in the memory of the database server, which will naturally control access to it by limiting it to only that process. It should be in some struct somewhere deep inside the mysql daemon, not tmpfs or anywhere else. The system's MMU will automatically protect it. – forest Feb 9 '18 at 14:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.