Search code examples
asp.net-mvc-4.net-4.5outputcachefips

Is Child Action Output Cache incompatible with FIPS?


I am trying to make my ASP.NET MVC 4 application FIPS compatible. Fortunately with .NET 4.5 ASP.NET already is using FIPS approved implementation of AES for viewstate and cookie encryption so there is no problem with that one.

However I ran into a weird issue. This can be reproduced with very minimalistic ASP.NET MVC App.

Create simple controller:

public class HomeController : Controller
{

    public ActionResult Index()
    {
        return View();
    }

    [OutputCache(Duration =  5)]
    public ActionResult Data()
    {
        return View();
    }

}

Create very simple views for Index:

<h2>Page</h2>
@Html.Action("Data")

and Data actions:

<h2>Data</h2>

So basically we are trying to do here is to use output caching on child action (works like a charm without FIPS enabled).

Now if we run it we'll get our dreaded FIPS screen of death:

[InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.]
System.Security.Cryptography.SHA256Managed..ctor() +10840001

[TargetInvocationException: Exception has been thrown by the target of an invocation.] System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +339 System.Security.Cryptography.CryptoConfig.CreateFromName(String name, Object[] args) +656 System.Security.Cryptography.SHA256.Create() +14 System.Web.Mvc.OutputCacheAttribute.GetChildActionUniqueId(ActionExecutingContext filterContext) +315
System.Web.Mvc.OutputCacheAttribute.OnActionExecuting(ActionExecutingContext filterContext) +118

And as you can see here the exception itself happens deep in MVC bowels in OutputCacheAttribute.GetChildActionUniqueId - obviously it is trying to use non FIPS approved SHA256 hasher, and I cannot see a way to instruct it to use a different one.

So first thing that would come to mind to try to resolve it would be to include following in the web.config file under configuration element:

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

However I realized as many people before me, that this setting has no effect for web applications (regardless if hosted in IIS or Cassini) even though it works perfectly fine for console applications on the same machine.

The common ASP.NET 2.0 solution of switching to triple des, has no effect either

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

After all in .NET 4.5 we already have FIPS approved AES used for those purposes.

Disabling FIPS on the whole machine (through registry or group policy tool) works perfectly fine, but of course the goal is to have it working with FIPS enabled at the machine level.

Is there something I may be missing? Any way to get it working withing stripping the app from all instances of output cached child actions?


Solution

  • This is the same issue as http://forums.asp.net/p/1979986/5672126.aspx?Can+t+use+SignalR+on+Win+Server+2008+with+FIPS+mode+on. The CLR team is aware of it and is considering a fix.

    In the meantime, you can use the same workaround as in the bug report above. Add the following to Application_Start in Global.asax:

     CryptoConfig.AddAlgorithm(typeof(SHA256Cng), "System.Security.Cryptography.SHA256");