Please do not use the .NET 2.0 HMACSHA512 and HMACSHA384 Classes


 


We’ve recently discovered a bug in the HMACSHA512 and HMACSHA384 classes which shipped in the .NET Framework 2.0.  This bug will cause these algorithms to produce incorrect results which are not consistent with other implementations of HMAC-SHA-512 and HMAC-SHA-384.  Unfortunately, we did not discover this bug until recently, and the shipping .NET Framework 2.0 on all platforms is affected by it.  The only two affected algorithms are the HMAC-SHA-512 and HMAC-SHA-384; other HMAC algorithms do produce correct values.

The next service pack to the .NET Framework will contain a fix for this bug, which will cause the HMACSHA384 and HMACSHA512 classes to produce correct HMAC values.  However, this will cause their output to be inconsistent with the output of the unserviced .NET Framework 2.0 classes.  In order to allow applications running on serviced framework to interact with applications running on the unserviced version, we will introduce two compatibility switches in the service pack.

First, both the HMACSHA512 and HMACSHA384 classes will have a new Boolean property, ProduceLegacyHmacValues.  By setting this property to true, the object will produce values which match what the unserviced .NET Framework would have produced.  You should set this property only once after you’ve created your HMAC object, and you will need to reset your key afterwards:


    public static void Test()


    {


        HMACSHA512 hmac = new HMACSHA512();


        hmac.ProduceLegacyHmacValues = true;


        hmac.Key = // … get the hmac key


 


        // …


        // use the hmac algorithm


        // …


    }


 


In order to help applications where it is expensive or impossible to change the code, we’ve added a new configuration switch for the application’s .exe.config file which will cause all HMAC objects created within the application to use the unserviced calculation.


<configuration>


    <runtime>


        <legacyHMACMode enabled=1 />


    </runtime>


</configuration>


 


Finally, in order to help debug any issues that arise when upgrading to the service pack, the first time an instance of either class is created, we will log a warning message to the event log and to any attached debugger.  The message text (which will hopefully help to point search engine results here as well) will be:

“This application is using the HMAC-SHA-384 or HMAC-SHA-512 keyed hash algorithm. The implementation of these algorithms were updated in service pack 1 of .NET Framework 2.0 and by default do not produce results consistent with the unserviced versions of the classes. For more information about the changes to the algorithms and how to disable this warning message please see the release notes for service pack 1.”

 


This warning will only be produced the first time an instance of either object is created in a process.  If the configuration switch to enable process-wide legacy mode is set, then we will suppress the message.  We’ve also provided a second configuration switch which will let you manually suppress the warning message for your application.


<configuration>


    <runtime>


        <legacyHMACWarning enabled=0 />


    </runtime>


</configuration>


 


If you need a replacement class for HMACSHA512 before the next service pack ships, then you can roll your own relatively easily.  Some code to do this would look like this:


internal sealed class MyHmacSha512 : System.Security.Cryptography.HMAC


{


    public MyHmacSha512(byte[] key)


    {


        if (key == null)


            throw new ArgumentNullException(“key”);


 


        HashName = “SHA512”;


        HashSizeValue = 512;


        BlockSizeValue = 128;


        Key = key;


    }


}


 


Similarly, a substitute class can be derived for HMACSHA384:


internal sealed class MyHmacSha384 : System.Security.Cryptography.HMAC


{


    public MyHmacSha384(byte[] key)


    {


        if (key == null)


            throw new ArgumentNullException(“key”);


 


        HashName = “SHA384”;


        HashSizeValue = 384;


        BlockSizeValue = 128;


        Key = key;


    }


}


 


This change will start to appear in future CTPs.  Again, I personally, and the CLR security team in general, are very sorry for any problems this may have caused in your applications.  Please feel free to ask any questions in the comments for this post, and I’ll make sure that they get answered as soon as possible.

Comments (19)

  1. Microsoft ha informado públicamente de un bug detectado hace poco en sus clases de criptografía HMACSHA512

  2. You’ve been kicked (a good thing) – Trackback from SecurityKicks.com

  3. El equipo de Seguridad del CLR del Microsoft .NET Framework ha anunciado que existen ciertas inconsistencias…

  4. CoqBlog says:

    Un bug a été découvert dans le Framework .NET 2.0 : les classes HMACSHA512 et HMACSHA384 sont susceptible

  5. webstudy says:

    I get this error when I publish my asmx webservice file to a windows 2003 server with FIPS enabled:

    This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms

    Is there a document that describes how to host a webservice on a FIPS compliant webserver?

  6. Nytewolf says:

    Now I wonder why this wasn’t found sooner….

  7. [Default] Spotlight on: Windows Vista Innovate on Windows Vista Innovate on Windows Vista helps fast-track

  8. Omri says:

    "The next service pack to the .NET Framework will contain a fix for this bug…"

    There is a release date for the next SP?

  9. shawnfa says:

    I don’t believe that we have announced a date for that service pack.  You should start to see this change appear in future CTPs of Orcas and other pre-release versions of the framework until the service pack is released however.

    -Shawn

  10. required says:

    I would suggest to keep away from the buggedHMACMode otherwise you’ll be incompatible in the real world.

  11. kurtrus says:

    We’re using System.Security.Cryptography.SHA256Managed as a way to encrypt passwords stored in our application database. Is that affected as well?

  12. shawnfa says:

    SHA256Managed is not affected, only the HMACSHA384 and HMACSHA512 algorithms are affected by the bug.

    -Shawn

  13. David Taylor says:

    Hi Shawn,

    A few months ago I found another bug with .NET 2 when using the XML Serializer under a certain condition.

    The bug is when deserializing XML that has elements referencing other inline elements by ID and when the element is a nillable primitive.

    I found this when integrating to web services on BEA WebLogic because it uses the specific type of encoding by default which triggers the bug on the .NET side.  You would not have picked this bug up when testing .NET against .NET because ASMX web services and the XML Serializer do not serialize out this particular way.

    I am *very* sure this bug is a runtime bug introduced by the new Nullable primitive support (ie Nullable<int>) and the mapping done when the XML is supplied in this specific format.

    Note that if you use the .NET 2 WSDL.exe utility (or VS 2005) to generate the proxy you see this bug; however if you use the .NET 1.1 WSDL.exe utility and them import the generated proxy into the VS 2005 project you do not see the bug.  This is because only the .NET 2 wsdl.exe tool uses the new nullable<T> feature rather than doing the prior (ie adding an additional boolean field to note if the value was supplied).

    Sorry for the long winded explanation – but I have not had enough time to follow this up with Microsoft; and if you are really doing a service pack to the v2 libraries you should include this.

    If you want more information ping me at: davidandrewtaylor [at] hotmail.com

  14. David Taylor says:

    BTW Shawn: Our solution to the bug I just posted was quite ugly -> A SoapExtension to intercept and reformat the incoming XML to reformat the incoming XML so the referenced IDs are not used; which gets around the specific bug in the .NET 2 deserializer.

  15. shawnfa says:

    Hi David,

    You can file your bug report on the MSDN Product Feedback Center (http://connect.microsoft.com/site/sitehome.aspx?SiteID=210) in order to see if the XML team has fixed that bug already or to get it on their radar.

    -Shawn

  16. Rich says:

    I happened to browsing the event log now in 2009 and noticed this error message.   I have a PhD in computer science but am a general Windows XP user.  The error message said I should come here for more information.  But this information is lousy.  I have no idea what I am supposed to actually *do*.  I’m not really interested in spending two hours figuring out if (1) I need to do something (2) what I have to do (3) what file I actually need to edit.   Could you add a pointer for poor suckers like me who land on this page, for some actual information?

  17. shawnfa says:

    Hi Rich,

    If your application does not need to interact with HMAC-SHA-384 or HMAC-SHA-512 data that was created with the .NET framework v2.0 RTM, then you can ignore this message.  In order to suppress the event log message, you can use a .exe.config file for your application using with the legacyHMACWarning switch set to 0 (you can see an example in the blog post).

    -Shawn

  18. Rich says:

    Still not satisfied.   I’m not writing an application.   I’m using standard Microsoft applications and other 3rd party software.

    I suspect it is Microsoft Dynamics CRM that is triggering the events, since Dynamics CRM is pretty fragile in general.

  19. klings says:

    Hi Shawn, thank you for your blog post.

    I tried to add the configuration you suggested would disable the warning message in the event log. I added this to our web.config, but I still get the warnings in the event log.

    The link I included does not mention this configuration element at all? Is it still supported in the framework?