This project is read-only.

How to manage key rotation?

Jan 23, 2013 at 2:47 AM
Edited Jan 23, 2013 at 2:52 AM

I reviewed the code and it seems the root secret bits come from the "SecurEntity" named certificate in the certificate store. Lets assume there is a database with, say, 10GB worth of data (all in just one table that has, say, 100K secure entities at 100KB  each).

If you had to perform key rotation to retire an old or compromised key/certificate, how would you do that?

I have my own quick view on it below, but am really curious about your thoughts.

Thanks
Sid 


My thoughts: Currently the only thing I see is writing custom application code to:

  1. Take SQL database offline
  2. Read (as cleartext via SecurEntity+installed Cert) an entity/row from the encrypted database 
  3. Write that entity (as cleartext) to a separate temporary database's temp table (that is assumed to be temporarily secure of course!)
  4. Do #2,#3 in a loop for all rows/entities
  5. Drop all existing rows in encrypted table
  6. Replace the "SecurEntity" named certificate with newer keying bits on the machine
  7. Read as cleartext the 1st entity from the temp database's, temp table
  8. Write as ciphertext (via SecurEntity) the 1st entity into the original database's just-cleaned out secure table 
    1. The paranoid can perhaps re-read the just-written entity using new key for verification purposes
  9. Do #7, #8 for every entity (all 100k)
  10. Securely wipe the temp db and temp table
  11. Deploy the new certificate to the production server
  12. Bring the SQL database containing the secure table back online
  13. Take a break!

In theory you could do an in-place decryption into the SQL tables but that's not possible since the root bits come from a single certificate => a single key (versus and old and a new key).

Coordinator
Jan 23, 2013 at 2:37 PM
Generally key rotation on encrypted data is avoided. Why not just do certificate renewal?

Sent from my Windows Phone

From: Sid_S
Sent: 1/22/2013 6:47 PM
To: rp_tomj@hotmail.com
Subject: How to manage key rotation? [securentity:430522]

From: Sid_S

I reviewed the code and it seems the root secret bits come from the "SecurEntity" named certificate in the certificate store. Assuming there is a database with, say, 10GB worth of data (all in tables that are secure entities, say 100k entries at 100kb each).

If you had to perform key rotation to retire an old or compromised key/certificate, how would you do that?

I have my own quick view on it below, but am really curious about your thoughts.

Thanks
Sid

My thoughts: Currently the only thing I see is writing custom application code to:

  1. Take SQL database offline
  2. Fetches, as cleartext, (thru SecurEntity) an entity/row from the encrypted database
  3. Write that entity (as cleartext) to a separate temporary database's temp table (that is assumed to be temporarily secure of course!)
  4. Do #2,#3 in a loop for all rows/entities
  5. Drop all existing rows in encrypted table (consisting of secured entities)
  6. Replace the SecurEntity certificate with one with identical name but new keys on machine running "this" code
  7. Read as cleartext the 1st entity from the temp database's, temp table
  8. Write as ciphertext the 1st entity into the original database's just-wiped out table (perhaps re-read with new key the just written entity for the paranoid for verification!)
  9. Do #7, #8 for every entity
  10. Securely wipe the temp db and temp table
  11. Bring the SQL database containing the secure table back online
  12. Take a break!

In theory you could do an in-place decryption into the SQL tables but that's not possible since the root bits come from a single certificate => a single key (versus and old and a new key).

Jan 23, 2013 at 4:13 PM
Edited Jan 23, 2013 at 8:06 PM

Well, the way it's used here (in SecretKeyStorage.cs), the secretKey is the same as the key used for AES encryption. That key is computed as

secretKey = aesKey = rsaSign(sha512(certificatePublicKey | certificatePublicName));

If I were to renew the certificate, usually I'd get a new public/private key pair. That in itself changes the hash and therefore the AES key. That means I can't decrypt previously encrypted data requiring the process I mentioned above. That's why I brought it up.

BTW, for SSL this doesn't matter since the data is transient + SSL's key rotation is loosely coupled with the public keys. 

Jan 23, 2013 at 8:20 PM
Edited Jan 23, 2013 at 8:21 PM

Also, TrueCrypt (whole disk encryption) adds one layer of abstraction. It stores a "master" key encrypted with your keyboard password on the disk header. That "master key" then encrypts the actual on-disk data.

If your master key is compromised, you need a full decrypt => reencrypt of entire disk via a new master key.

If your keyboard password is compromised (more likely), Truecrypt can simply decrypt master key (using old keyboard password) => reencrypt master key (using new keyboard password). The master key itself stays the same, so you don't have to perform a full data encrypt/decrypt. That is convenient security for a more likely scenario.

Why the above story?

Well, SecurEntity re-derives the master key each time. It would instead use the certificate as the "keyboard password" above and save the master key (encrypted of course) back to some non-secure persistent storage (SQL db/table/blob storage etc). This would solve the problem of a compromised certificate without requiring a full dB decrypt=>encrypt cycle.

I had hoped to contribute directly into this project but based on our needs and deadlines we will most likely custom write our own crypto layer (using of course well published crypto standard underneath). I'm going to ponder on the approach for another day. What's the process for submitting patches? I'm familiar with GIT and it's system of the master requesting a GIT pull from the feature submission branch. SVN or TFS - no idea!

Coordinator
Jan 23, 2013 at 10:31 PM
On windows renewing an encryption cert does not result in result in replacing the key

Sent from my Windows Phone

From: Sid_S
Sent: 1/23/2013 8:14 AM
To: rp_tomj@hotmail.com
Subject: Re: How to manage key rotation? [securentity:430522]

From: Sid_S

Well, the way it's used here (in SecretKeyStorage.cs), the secretKey is the same as the key used for AES encryption. That key is computed as

aesKey = rsaSign(sha512(certificatePublicKey | certificatePublicName));

If I were to rotate renew the certificate, usually I'd get a new public/private key pair. That changes the AES keys and that would mean I can't decrypt previously encrypted data. Seeing this was the main reason I brought this up.

BTW, for SSL this doesn't matter since the data is transient + SSL's key rotation is loosely coupled with the public keys.

Jan 24, 2013 at 3:16 AM

I presume you’re taking about EFS. To be honest I haven’t looked at the specific implementation of EFS’s trust chain but I’m sure it begins with a certificate and ends with an array of secret bytes (=key) that encrypt the user/filesystem data.

More importantly, while the discussion of EFS differences might be interesting, I’d like to refocus to database security. It seems like there is no provision to recover from a compromised certificate or a compromised secret key. All the remediation techniques would be needed to be implemented outside as a separate piece of code. Actually that’s the tricky part to minimize commercial downtime ...

From: tomjones [email removed]
Sent: Wednesday, January 23, 2013 2:31 PM
To: siddharth.shetye@gmail.com
Subject: Re: How to manage key rotation? [securentity:430522]

From: tomjones

On windows renewing an encryption cert does not result in result in replacing the key


Coordinator
Jan 24, 2013 at 6:45 AM
Compromised certs are handled in the usual PKI way (revocation & reissue), but they really have no impact on the security of the data. If you do export the key, it is recommended to encrypt it. It is possible to mark keys on production boxes as non-exportable. The only use of a cert for an encryption key is when you want data sent by a (potentially) untrusted party to you. The cert adds little to EFS but is required by the crypto provider. The trust chain only serves to tell an untrusted party who you are so they can send encrypted data to you, which is not of much interest in EFS (unless you are using EFS to get bulk encrypted data from a third party, but there are easier ways than EFS to do that).
If you lose the key, you are in a world of hurt; the data is in all probability gone already.
That sort of key loss would require the extraordinary measures you outlined below and would make a good addition to securenity to have a generic solution.


From: [email removed]
To: [email removed]
Date: Wed, 23 Jan 2013 19:16:38 -0800
Subject: Re: How to manage key rotation? [securentity:430522]

From: Sid_S
I presume you’re taking about EFS. To be honest I haven’t looked at the specific implementation of EFS’s trust chain but I’m sure it begins with a certificate and ends with an array of secret bytes (=key) that encrypt the user/filesystem data.

More importantly, while the discussion of EFS differences might be interesting, I’d like to refocus to database security. It seems like there is no provision to recover from a compromised certificate or a compromised secret key. All the remediation techniques would be needed to be implemented outside as a separate piece of code. Actually that’s the tricky part to minimize commercial downtime ...

From: tomjones [email removed]
Sent: Wednesday, January 23, 2013 2:31 PM
To: siddharth.shetye@gmail.com
Subject: Re: How to manage key rotation? [securentity:430522]


From: tomjones
On windows renewing an encryption cert does not result in result in replacing the key



Read the full discussion online.
To add a post to this discussion, reply to this email (securentity@discussions.codeplex.com)
To start a new discussion for this project, email securentity@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com
Jan 24, 2013 at 8:47 PM

Sid - can you please provide more detail on your key replacement scenario need? For example, I'm wondering if it's driven by a public compliance requirement. That helps us prioritize work items (want to add one?).

We've discussed a more general need to create a plaintext replica of the database. Such a feature would be one way to address crypto migration needs. It's tough to do this in a general way, though, because while an in-place row decryption feature could ignore the integrity checks, re-encrypting would want to result in correct integrity, and you can't do that without knowledge of the schema, including deep inspection of child POCO objects.

Jan 25, 2013 at 6:55 AM

Hi Dan,

The compliance standard is the ISO 27002 (http://www.iso27001security.com/html/27002.html), specifically under the two sub-sections: "Access Control" and "Business continuity management". Note that ISO27002 is an abstract framework, the company then has to implement concrete policies ("key rotation every 24 months") and that too you don't have to implement every recommendation. It's like the Food pyramid - you won't die if you deviate 1:1; but it's a good recommendation to stick to.

That's what is driving the key rotation concern. I agree that key rotation is a painful problem to solve. Right now our policy is to take databases offline and re-encrypt. An 'online' method would be great. From the top of my head, one could have a KeyVersion in the crypto metadata to divide all entities into "encrypted with old key" and "already encrypted with new key" space and avoid the cleartext database altogether. To revert back to a fully unencrypted database (if divorcing SecurEntity) you could have the target encryption as "DoNothing" after decrypting the cipher text off old key.

Regarding integrity checks, it's best to use an authenticated-encryption (AE) modes like GCM or OCB. Generic information about the class of crypto algorithms is at (http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html). AE modes like GCM or OCB are basically new modes (just older CBC) of using existing symmetric ciphers (like AES128) underneath. The good thing is you get data privacy (traditional encryption) + data integrity (HMAC) all in one operation. So a single IV, single key with double advantage. This means your crypto metadata can drop by 50%!

AE modes are NIST approved and OCB recently (2 weeks back) dropped it's licensing terms to much simpler ones (http://www.cs.ucdavis.edu/~rogaway/ocb/license.htm). On the flip side, these are relatively newer, so fewer implementations out there. I think Microsoft hasn't implemented a .NET version and there is a library out there that implements OCB (http://www.bouncycastle.org/csharp/index.html).

It's not "my project" but I would add the following 3 items (in decreasing priority)

  1. Supporting database first model in a documented manner ("you must have a column of type X defined in the table and supply the name of the column to SecurEntities on dB context initialization. All your secure tables must use the same column name you provide. blah blah")
  2. Solve the key rotation / 'return database to clear state' problem transparently
  3. move to AE ciphers

Thanks!
Sid

PS: TomJones: "Compromised certs are handled in the usual PKI way (revocation & reissue)". That's fine. For PKI. But for SecurEntity, because of the way it's hardwired into the heart of the certificate, ANY new certificate resets the masterKey for SecurEntity because it is aesKey = rsaSign(sha512(certificatePublicKey | certificatePublicName)). With your master key reset, how would you plan on avoiding the decrypt=> encrypt cycle? SecurEntity doesn't really see the KI in PKI, it only consumes the certificate as a bucket of bits for entropy that's used as the key.

Jan 25, 2013 at 7:00 AM
Edited Jan 25, 2013 at 7:02 AM

To simplify even more 

aesKey = rsaSign(sha512(certificatePublicKey | certificatePublicName))

=>

aesKey = f(certificatePrivateKey, certificatePublicKey, certificatePublicName)

So if you change ANY of the above parameter (which you would for a meaningful revocation), you'd be changing the AES key. Also, because they are cryptographically mixed, you can't synthesize a new public name or some other field so that you can come back to the older AES key. 

BTW, if my understanding of SecurEntity's keygen is fundamentally flawed, please do let me know :)

Jan 25, 2013 at 6:53 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jan 25, 2013 at 6:58 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jan 25, 2013 at 7:01 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.