views:

367

answers:

3

If you enable the "Use FIPS compliant algorithms for encryption, hashing, and signing" security policy option in Windows, attempting to use many of the cryptographic classes in the .NET Framework will result in an InvalidOperationException. By default, ASP.NET uses AES to encrypt the ViewState blob, so it fails. You can work around this by adding a key like this to web.config:

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

And that covers you for basic ASP.NET use. My problem is this: I have a large, complex ASP.NET web applications that makes heavy use of ScriptManagers (the foundation of ASP.NET AJAX) and needs to be deployed by a government customer who must enable this FIPS policy setting. Any ASP.NET page with a ScriptManager on it throws this exception:

[InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.]
   System.Security.Cryptography.SHA1Managed..ctor() +3607454
   System.Security.Policy.Hash.get_SHA1() +45
   System.Web.Handlers.ScriptResourceHandler.GetAssemblyInfoInternal(Assembly assembly) +85
   System.Web.Handlers.ScriptResourceHandler.GetAssemblyInfo(Assembly assembly) +99
   System.Web.Handlers.RuntimeScriptResourceHandler.GetScriptResourceUrlImpl(List`1 assemblyResourceLists, Boolean zip, Boolean notifyScriptLoaded) +525
   System.Web.Handlers.RuntimeScriptResourceHandler.System.Web.Handlers.IScriptResourceHandler.GetScriptResourceUrl(List`1 assemblyResourceLists, Boolean zip, Boolean notifyScriptLoaded) +910
   System.Web.Handlers.RuntimeScriptResourceHandler.System.Web.Handlers.IScriptResourceHandler.GetScriptResourceUrl(Assembly assembly, String resourceName, CultureInfo culture, Boolean zip, Boolean notifyScriptLoaded) +193
   System.Web.UI.ScriptReference.GetUrlFromName(ScriptManager scriptManager, IControl scriptManagerControl, Boolean zip) +306
   System.Web.UI.ScriptManager.RegisterUniqueScripts(List`1 uniqueScripts) +169
   System.Web.UI.ScriptManager.RegisterScripts() +407
   System.Web.UI.ScriptManager.OnPagePreRenderComplete(Object sender, EventArgs e) +200
   System.Web.UI.Page.OnPreRenderComplete(EventArgs e) +11041982
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3672

Even adding the <enforceFIPSPolicy enabled="false"/> element to web.config does not resolve the exception.

Is there any way to configure ASP.NET such that ScriptManager can be used with the Windows FIPS security policy?

A: 

Iam having exactly the same problem on Windows 2008 R2. I've also tracked it down to the ScriptManager control causing the error. The problem can easily be re-created by creating a blank ASP.NET 3.5 web page and dropping only a ScriptManager control on it. Publish the code to be non-updatable and then enable FIPS on the server. Previously in Windows 2003 you could add the following machineKey Settings to the web.config to get the code to run but it doesn't work anymore.

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

The weird thing is, the exact same code works fine on a Windows 2003 x86 server that has FIPS enabled using ASP.NET 3.5 with the same machinekey settings. I've tried everything imaginable and can't figure out a workaround. Unfortunately, disabling FIPS isn't a viable solution to this problem. Any help to get me out of this bind would be greatly appreciated.

chrisj
+2  A: 

Update from Microsoft: The hot fix is available at http://code.msdn.microsoft.com/KB981119

The answer is that you can't use ScriptManager with a FIPS enabled server. :(

The static method GetAssemblyInfo of class System.Web.Handlers.ScriptResourceHandler creates a hash object that is not FIPS compliant. This was changed between .Net 3.5 SP1 and .Net 3.51

(System.Web.Extensions version 3.5.30729.196)
XP/2003/2008 .Net 3.5 SP1

private static Pair<AssemblyName, DateTime> GetAssemblyInfoInternal(Assembly assembly)
{
    return new Pair<AssemblyName, DateTime>(new AssemblyName(assembly.FullName), GetLastWriteTime(assembly));
}

(System.Web.Extensions version 3.5.30729.4926)
Win7/2008R2 .Net 3.51

private static Pair<AssemblyName, string> GetAssemblyInfoInternal(Assembly assembly)
{
    AssemblyName first = new AssemblyName(assembly.FullName);
    return new Pair<AssemblyName, string>(first, Convert.ToBase64String(new Hash(assembly).SHA1));
}

Obviously the change from the time date stamp to the hash broke the FIPS compliance. We have opened a support case with Microsoft.

John Taylor
+1  A: 

Microsoft has released a hotfix to address this problem: KB981119. I don't think the hotfix is publicly available through the Microsoft Web site.

chrisj