Friday, July 13, 2018

.NET 4.7.1 (and higher) no longer supports SHA1 in SignedXml

There are plenty of subtle changes between .NET 4.7.0 (and lower) and .NET 4.7.1, however one of the changes hurt us badly. It looks like the SignedXml no longer supports SHA1 as the hashing method.

What it causes is the

System.Security.Cryptography.CryptographicException : Invalid algorithm specified
...
     at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)
     at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
     at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)
     at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()

The resolution is to put an additional section in the app's config file that switches the use of insecure hashes on:

  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms=true;
                                         Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms=true" />
  </runtime>

If these switches seem to be ignored (we observed this in web apps where this was put in the web.config rather than an app.config, simply replace it with the code that you put in the global app class in the Application_Start:

protected void Application_Start(object sender, EventArgs e)
{
   ...
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
}

No comments: