I'm writing a multi-tenant application that interacts with a couple of different APIs on behalf of each customer. Obviously, we need to store private keys for these various different APIs in the database so that we can connect to them. Goes without saying, I need to encrypt those.
I wanted to use a separate encryption key for each tenant on the system (I'm using openssl_encrypt with AES-256-CBC). To accomplish this, I have a separate "crypto" database. The tenant_keys table contains the following columns:
- A
tenant_hash
, which is a has of a random value stored in the tenant's settings table, used for lookup - A
tenant_key
, which is the tenant's unique encryption key. - A
key_timestamp
that I'll use in the future to periodically rekey tenants
The obvious weakness is that if the database were stolen, the attacker would have all of the keys. To combat this, I've generated a "master key" that is stored as a text file on the server. This master key is then used to encrypt all of the various tenant keys. So, when a session is first initiated and the tenant is looked up, the tenant's key is decrypted and stored in the session. So, here are my questions:
- Is there a better way to secure each tenant key (perhaps some sort of key server, but building an entire CA hierarchy and such seems like overkill vs protecting the
master_key
file with good chmod settings)? - Is there a safer way to store the tenant's key ephemerally without needing to do a round of decryption (costs CPU time) each time we need to use it, besides in the PHP session? The PHP sessions will ultimately be stored in some sort of shared storage (probably redis) as the environment will be clustered.