Search code examples
c#.netcryptographykeymessage

ComputeHash Calls Inexplicably Differ


Why do the following two methods of calling ComputeHash result in different result lengths? Seems like the code should produce equivalent results.

byte[] KeyBytes = Convert.FromBase64String("KgMLuq+k1oCUv5bzTlKAJf/mGo0T07jTogbi6apcqLa114CCPH3rlK4c0RktY30xLEQ49MZ+C2bMyFOVQO4PyA==");
byte[] MessageBytes = System.Text.Encoding.UTF8.GetBytes("ae06fcd3-6447-4356-afaa-813aa4f2ba41;70aa7c25-c74f-48be-8ca8-cbf73627c05f1418068667");

// works
byte[] HashBytes1 = new System.Security.Cryptography.HMACSHA256(KeyBytes).ComputeHash(MessageBytes); // correct - 32 bytes

// doesn't work
System.Security.Cryptography.HMAC hmac2 = System.Security.Cryptography.HMACSHA256.Create();
hmac2.Key = KeyBytes;
byte[] HashBytes2 = hmac2.ComputeHash(MessageBytes); // wrong - only 20 bytes

Solution

  • That's simple: look at the remarks of the static HMAC.Create method:

    By default, this overload uses the SHA-1 implementation of HMAC. If you want to specify a different implementation, use the Create(String) overload, which lets you specify an algorithm name, instead.

    Now HMACSHA256 inherits from HMAC, but it doesn't define it's own static Create method. So you would still have to use HMAC.Create("HMACSHA256").

    It's probably better to use the HMAC.Create(String) than using HMACSHA256.Create(String) class here, as not to confuse matters.

    Note that the SHA-1 outputs 160 bits or 20 bytes, so this indeed explains the odd output size...