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:
So this brings up a couple of questions:
<enforceFIPSPolicy enabled="false"/>
?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.