Our app has the <machineKey> set in the web.config:

<machineKey validation="HMACSHA256" validationKey="some-validationkey" decryption="AES" decryptionKey="some-decryption-key" />

It is used to encrypt/decrypt many things built into ASP.NET including:

  • Forms authentication tickets
  • Anonymous identification module tickets
  • Anti-forgery tokens (in ASP.NET MVC)

If the machine key is compromised, it means an attacker could decrypt all of these things. A security best-practice is to rotate your keys often (or at least when you think it might be compromised). This would require the ability to version each piece of encrypted data so that rotation is possible when needed.

If you change the machine key and re-deploy your site, your existing users that have encrypted data (e.g. cookies, form fields) will most likely trigger exceptions on their next request because the data can no longer be decrypted. For example, the AnonymousIdentificationModule will throw a CryptographicException: Error occurred during a cryptographic operation.. This makes complete sense if the AnonymousIdentificationModule doesn't have the ability to version encryption/decryption.

One method I was thinking of using is implementing custom HashAlgorithm and SymmetricAlgorithm with versioning built-in to delegate to real algorithms. For example:

  1. Registering them with CryptoConfig.AddAlgorithm():

    CryptoConfig.AddAlgorithm(typeof(MyCustomHashAlgorithm), "MyCustomHashAlgorithm");
    CryptoConfig.AddAlgorithm(typeof(MyCustomSymmetricAlgorithm), "MyCustomSymmetricAlgorithm");
  2. Change the <machineKey> to use the custom algorithm:

    <machineKey validation="alg:MyCustomHashAlgorithm" validationKey="some-validationkey" decryption="alg:MyCustom" decryptionKey="some-decryption-key" />

However, I'm concerned about implementing the HashAlgorithm and SymmetricAlgorithm. I do not want to accidentally introducing security holes, and this is an easy place to do this. Also, this feels like a huge hack since it really belongs at the place that uses the algorithm (I think).

Another approach is re-implementing all of the functionality that uses the machine key but add versioning. It's not possible to change the existing .NET classes.

How do you handle this problem in production? I know StackOverflow is written in ASP.NET MVC, so how do they handle it?

Side note: For security reasons, we don't actually store the <machineKey> in the web.config directly (it is outside of source control).

Related posts

Recent Viewed