Please do not use the .NET 2.0 HMACSHA512 and HMACSHA384 Classes
http://blogs.msdn.com/shawnfa/archive/2007/01/31/please-do-not-use-the-net-2-0-h
macsha512-and-hmacsha384-classes.aspx
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.
最新评论