Score:1

Key rotation and versioning for encryption at rest

jp flag

I'm working with a dev team who are implementing encryption at rest at the application level. It's for particularly sensitive fields inside an RDB. (The underlying DB storage has an additional layer of encryption, but that's off topic here.) We're using a Spring's AesBytesEncryptor and related classes for that.

We have not fully solved key rotation yet, and i'm investigating how to do that in a secure manner. We'd like to use a separate key-rotation tool that would run isolated from the application that consumes the data. That key-rotation tool will access the DB asynchronously, and perform re-encryption in small chunks. (Not in a single DB transaction that would re-encrypt all data.)

In order to do so, we plan that the application can be configured with multiple (well, two) keys at the same time. It would always use the first key to encrypt new data. But it could decrypt old data with either key, depending on whether the key-rotation tool has already re-encrypted the particular field.

Now the question is, whether we need to store additional key versioning meta-data in the DB? That would tell the application which decryption key to use for any chunk of data.

I'm hoping to get around that by relying on some form checksum instead. The application would just try decryption keys in turn, until it gets a decrypted value that does not break the checksum.

Imho, Spring's AesBytesEncryptor might already be providing all that we need. But the reliability will depend on what mode we use. Here's my thoughts about the two supported modes:

  • Mode AES/CBC/PKCS5Padding: Does not have a checksum per-se, but the padding will likely break when attempting decryption with the wrong key. However this depends on the size of the padding, which depends on plaintext data size. Worst case there might be as little as 1byte of padding. So chances to hit the correct padding with wrong decryption key might be as high as 1/256. That seems too risky to rely on.

  • Mode AES/GCM/NoPadding: Here the GCM "authentication tag" serves as a form of checksum. As far as I understands it's always 128bits (16 bytes) long for AES. That means chances to hit a valid authentication tag with the wrong decryption key are roughly 1/(2^128). That is practically never, so I think it should be suitable for our application.

Are the above assumptions correct? What did I get wrong?

Do you think it's robust enough to try multiple decryption keys in turn during key rotation, when using AES/GCM/NoPadding? Or do we need to store key versioning information alongside the encrypted data after all?

Or, is there an even better way to solve key rotation in our scenario?

SAI Peregrinus avatar
si flag
Do you need to rotate the actual data encryption key (DEK)? The common way is to have two keys: a data encryption key that never changes, and is never stored. That's encrypted with a "key encryption key" (KEK) and that encrypted value (and the KEK) is stored. To rotate keys, you decrypt the DEK (into RAM, as usual) using the old KEK, then encrypt it using the new KEK and store that ciphertext. This can be done in a single database transaction.
meeque avatar
jp flag
Yes, we're aiming for a KEK/DEK approach. However there are many different flavors to that, e.g. when it comes to [granularity](https://cloud.google.com/kms/docs/envelope-encryption#balancing_deks_and_keks). Or, if and how KEK/DEK need to be rotated. I've come to the conclusion that we should be capable to rotate both KEKs and DEKs. And I think this question is relevant to either of them. That's why I tried to avoid the KEK/DEK topic. That said, if anyone wants to change my mind, I could ask a separate question for that... Either way, I'd still like feedack on this one:)
meeque avatar
jp flag
Anyone else want to take a shot at the original question?
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.