Developing a web application that automatically rotates encryption keys used to encrypt data stored in a database

StackOverflow https://stackoverflow.com/questions/11094428

Question

Assuming I have a ASP.NET MVC 3 application that runs in a web farm where each web server belongs to a workgroup (as appose to a domain with shared accounts). The web farm is also auto scalable, meaning that the number of instances are dependent on the load. Sensitive data is encrypted and decrypted when stored/retrieved from the database. The symmetric and asymmetric keys are stored on each machine and protected with ACL and encrypted using DAPI (using the machine key).

For compliance and security reasons it is required that keys be rotated on a regular interval. How would you design/modify the system to automatically rotate keys at a regular interval without bringing the system offline? Assume that there are an arbitrary number of tables each with an arbitrary number of columns that are encrypted using the keys.

Many Q&A are related to which algorithms to use and how to secure the keys, however few actually address how to design and implement an application that would allow those keys were to be rotated, especially in a dynamic environment (autoscaling environment) sharing a database.

Was it helpful?

Solution

Having multiple keys in your system

When having multiple encodings (or encryption schemes, keys) what you usually want to do first is introduce some kind of versioning scheme as you need to know which key has been used for this particular piece of data. You have several choices for this:

  • Timestamps: Save the timestamp the data has been encrypted with the data. Then divide time into intervals of some length where the same key is used.
  • Version numbers: You can also simply assign increasing version numbers.
  • Key fingerprint: Store they key's fingerprint with the data

In every case, you need to store all keys that are currently in use to be able to decrypt data. When reading data, just look up the key matching your version identifier and decrypt. When writing, use the currently active key and store the encrypted data + your version identifier. You can retire (aka delete) a key when you are sure there is no data encrypted with this key in your database.

Deploying new keys

Whenever you roll over to a new key, this key has to be generated and deployed. You can do this in a central fashion or use some distributed key agreement protocol.

Re-encrypt data

If you need to re-encrypt data, you can do it in two ways:

  • Background process: Having a background process that just retrieves N data items with an old versioning identifier, decrypts and re-encrypts it and stores the result. Sleep a bit between runs to not overload your system.
  • Update on access: Whenever you read data and you notice that it has an old versioning identifier, re-encrypt with the current key and store the result. This might not re-encrypt everything depending on your data-access pattern, so an additional background process might be necessary.

Asymmetric crypto

If you are using asymmetric crypto (I guess for example for storing credit card numbers, webservers only having the public key to encrypt and the payment processor having the private key to decrypt) it gets a bit tricky, since only the machines with the private keys can re-encrypt data. All other aspects are the same.

OTHER TIPS

Google's Keyczar provides such a framework, but there ins't a .Net version.

Maybe you could wrap the C++ version in a .Net wrapper ?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top