Cryptographic Agility and Key Management

405 Views Asked by At

I have a design question. I have a web application that uses .NET encryption APIs to encrypt/decrypt data. (App uses old crypto algorithms like MD5 and SHA-1). Also, app hard-codes the encryption keys in the production code.

I would like to; 1 ) Update existing old algorithms (MD5 and SHA-1) to new ones. 2 ) Move encryption keys from source code to a secure share. 3 ) Can change the encryption keys easily and regularly

My Design;

Algorithm Update For the algorithm update, we use specific .NET implementations of crypto algorithms. We use classes like MD5CryptoProvider or RijndaelManaged. These are all hard-coded. I am going to remove the specific algorithm dependency and make it more agile like;

HashAlgorithm algo = HashAlgorithm.Create(MyPreferredHash.ToString()); algo.ComputeHash(...);

MyPreferredHash value will be loaded from a config file so that we can change this when we want to.

Question: Upgrading the code is easy to do this. However do you see any potential issues with changing crypto algorithms? We do not store any encrypted or hash data anywhere and web application is stateless. All the hash values are generated and appended to url strings and decrypted from another pages. Therefore, no data is stored. Except the cookies. When we encrypt cookie and send it back to user, we decrypt it when server receives it. In this case, i thought of destroying the cookie and send a new one to the client. Is this reasonable? Any other issues you think of ?

Key Management

Second part of the design, is to remove hard-coded keys from source code to secure share. After this, I need to be able to rollout new encryption keys. Each encryption key will be associated with a expire date. When we rollout a new encryption key, new key will be used for encryption and decryption. If it fails to decrypt, then we can try old keys. Old keys will be used for decryption or verification until their expire date. When they pass their expire date, they should retire.

For the storage; I am thinking of storing the encryption keys in a config file in the local machine as "encrypted" by a master key which will reside in a secure share. Therefore, anybody who doesn't have access to this secure share will not be able to see the master key. Master key will be loaded from secure share to machine registry when a machine reboots. The encryption keys in the local machine will be loaded from config file (local) and decrypted by master key in registry.

This storage choice will give us storing only one master key in a secure share and also historical changes to the encryption keys as we will store them in version control system.

The challenging part is the key change/update.

What is the recommended key change algorithm here for a distributed web application? If we are doing partial deployment after a release, not all the machines will have the same config file content (e.g. new encryption key added). All site deployment can take 1-2 weeks. This is also another concern that if we should wait for all deployments complete so that these keys will be active after that.

Any other feedback?

1

There are 1 best solutions below

0
On

You are quite right to design your app to be agile in the face of unknown future attacks on particular encryption algorithms.

The simplest way to future-proof your app in a robust way would seem to be to switch to using a standard data format for your encrypted information, and use a standard library to do the hard lifting. The choice of a specific standard to use would depend on what kind of data formats you're working with, but there are good candidates to choose from. Then when there is a future attack, you can just change some parameters, or update to the latest version of the implementation.

Doing crypto is very tricky. Best to leave it up to the experts.