How would you design a server/client system where a client is granted a key to encrypt/decrypt data, but the key could be revoked/redistributed by the server? Data encrypted prior must still be readable with the new key.

A simple scenario:

  1. Client wants to send a document to a server
  2. Client encrypts the document with some client-side credentials and sends to server
  3. Server receives document and stores in database
  4. Client requests document, receives, then decrypts. The roundtrip is complete.

Now, suppose the client credentials are compromised and key used to encrypt/decrypt data is stolen. The client changes their password, etc, but the key that can decrypt incoming data is still an issue.

My question is about redistributing an encryption key without having to re-encrypt all of the clients data. Are there any patterns that can help me with this? It feels like a variation of symmetric encryption with a KEK and DEK, but I'm having trouble figuring out how to encrypt something on the client side without exposing the DEK.


KEK and DEK will not be helpful to you. In these schemes, the key that encrypts the data (DEK: data encryption key) never changes. Only the envelope/wrapper key (KEK: key encryption key) that protects the DEK changes. The KEK is the one that is protected by the user password. You can replace the user password & KEK and then protect the original DEK with the new KEK but the data is still encrypted with the original DEK, unless you replace DEK but that requires decrypting the document with the old DEK and encrypting it again with the new DEK.

If your solution relies on decryption at the client side, there is no way of avoiding storing DEK at the client. The client needs it to encrypt/decrypt. In the event of user password and thus KEK being compromised (the latter requires access to the device), then you can assume DEK is also compromised too (b/c it is encrypted by KEK). In this scenario, you need to re-encrypt all documents if the adversary can access the encrypted document too.

One alternative could be to not store DEK at the client-side permanently, rather provide it upon request, decrypted via KEK sent to your server in a SSL/TLS session from the client.

  • This can allow your app to store additional logs for incident response and also provide opportunity to perform anomaly detection etc at the server side.
  • But, this is just an improvement and doesn't solve the underlying problem: you're still sending the DEK to client, it's just not being stored permanently there anymore.
  • Plus, this eliminates the privacy of your users if that's a concern (i.e. the server knows and stores DEK, after KEK is received from the client).
  • Of course, if it comes to this point, why not perform all decryption/encryption at server side (the only thing I can think of: a) saving on server cloud cost by not handling the CPU intensive work at the server, and b) maybe avoiding the probably of unintentionally storing the decrypted versions of sensitive client documents on the server, i.e. memory dumps, error logs etc.)
  • Thank you your answer, @K4M! This is just the summary I was looking for. I've decided to go with server side encryption as this is just a learning project and doing so simplifies things for me considerably. – EddieH Aug 22 '20 at 13:50
  • You're welcome! Please up-vote if you find it helpful. – K4M Aug 23 '20 at 5:35
  • Alas, my reputation is too low for the publicly displayed post score to be affected. I'm told the up-vote is still recorded though. – EddieH Aug 23 '20 at 19:13
  • Thanks. Didn't know. New to the site. – K4M Aug 24 '20 at 5:38

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.