enforceFIPSPolicy flag in web.config doesn't seem to working for web application

Ben McCormack picture Ben McCormack · Jul 11, 2011 · Viewed 12.3k times · Source

I'm trying to set up a web application to work in an environment where the FIPSAlgorithmPolicy is set to 1 in the Windows registry (specifically, HKLM/SYSTEM/CurrentControlSet/Control/Lsa). When this flag is enabled, any call to the class MD5CryptoServiceProvider will cause an Invalid Operation Exception to be thrown with the following stack trace:

[InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.]
   System.Security.Cryptography.RijndaelManaged..ctor() +10480142
   System.Web.Configuration.MachineKeySection.ConfigureEncryptionObject() +439
   System.Web.Configuration.MachineKeySection.EnsureConfig() +152
   System.Web.Configuration.MachineKeySection.GetEncodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32& length) +48
   System.Web.UI.ObjectStateFormatter.Serialize(Object stateGraph) +381
   System.Web.UI.Util.SerializeWithAssert(IStateFormatter formatter, Object stateGraph) +59
   System.Web.UI.HiddenFieldPageStatePersister.Save() +89
   System.Web.UI.Page.SaveAllState() +1117
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3864

Based on what I read in this article, you're supposed to be able to add the following to your config file to disable the algorithm check:

<configuration>
    <runtime>
        <enforceFIPSPolicy enabled="false"/>
    </runtime>
</configuration>

This works for me in a test Console application by modifying its app.config. However, it doesn't seem to work when a modify a .NET 2.0 web application's web.config.

What's interesting to me is that even though I'm catching all exceptions when I go instantiate an MD5CryptoServiceProvider in code, it doesn't seem to even make it to that portion of my code. This is the code that's called in my test app:

    protected string printSomething()
    {
        string toPrint = String.Empty;
        try
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            toPrint = "Created algorithm.";
        }
        catch (Exception e)
        {
            toPrint = e.ToString();
        }
        return toPrint;
    }

And this is what I see when I visit the page:

screenshot of YSOD

So this brings up a couple of questions:

  • Why is IIS throwing a YSOD instead of allowing my app to catch the exception?
  • What do I need to do so that my web app is able to use <enforceFIPSPolicy enabled="false"/>?

Answer

vcsjones picture vcsjones · Jul 11, 2011

1). Your code isn't throwing the exception. ASP.NET is doing something else. ASP.NET is trying to serialize the ViewState; which can be encrypted by the machine key. When ASP.NET does this internally; it uses the RijndaelManaged class (which is not FIPS 140 compliant; and blows up. Likewise; when ASP.NET tries to encrypt / decrypt a forms authentication ticket; it will use the machine key as well.

You have a few options for the Machine Key issue. You can use 3DES (which will always use a FIPS compliant implementation by setting the MachineKey in your web.config to look like this:

<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" validation="3DES" decryption="3DES" />

2). I'm not sure why your flag is being ignored. It shouldn't be. I'll edit if I figure anything out.

Note that the MD5CryptoServiceProvider might still bomb. MD5 is not a FIPS compliant hash. As far as I know; only the SHA-1 and SHA-2 hash algorithms are in .NET. The crypto functions that end in CryptoServiceProvider rely on the Windows CSP; which also acknowledges that flag. An alternative would be to use BouncyCastle instead of .NET's implementation since it doesn't care about that flag.