Question

I have an edge case. I'm building code that reads binary datafiles produced by a commercial, closed source tool. The information on the data format is specified in a document.

For data integrity checks, the vendor's spec calls for an HMAC based on SHA1, using a key derived from a password as per RFC2898. Many programming environments have a class called HMACSHA1 to produce these hashes.

For data streams of non-zero length, I can successfully calculate the Hash, and the calculation in my code agrees with the vendor's implementation. In other words, my code can read and authenticate files written by the vendor, and vice versa.

However, when the length of the data stream is zero, the vendor's tool emits a Hash which is NOT all zeroes. I don't know where it comes from, if there is no message to run through the HMACSHA1.

For HMACSHA1, or for any HMAC, is the MAC defined for the edge case of "a null message"?

I am using .NET, and the class System.Security.Cryptography.HMACSHA1, although I believe my question is platform-agnostic.


There is one platform-specific bit: When I try to get the Hash property on an instance of that type, if I have not run any data through the instance, I get

Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Security.Cryptography.HashAlgorithm.get_Hash()

This isn't surprising to me at all, since there is nothing to hash.

any hints?

Was it helpful?

Solution 2

Bumbling around in the dark, I found what I needed. Not sure if HMACSHA1 is defined for the case of a zero-length message, BUT

I did find that on .NET, if I call HMACSHA1.ComputeHash() and pass a byte array of length zero, I get the expected, desired hash.

Sorry for the noise, we now return you to your previously scheduled programming.

OTHER TIPS

HMACSHA1 is defined for all inputs of n bits, where 0 <= n < 2^20 - 160.

HMACSHA1 is defined as SHA1( K* || SHA1( K** || text ) ), where K* and K** are 20 bytes long values derived from the key (see FIPS 198a).

So HMACSHA1( "empty string" ) = SHA1( K* || SHA1( K** ) ), which is very well-defined.

Have to tried to add a zero length array to the hash? The underlying object is likely created during the first call.

Using several implementations hashing a zero length file gives:

MD5   : d41d8cd98f00b204e9800998ecf8427e
SHA-1 : da39a3ee5e6b4b0d3255bfef95601890afd80709
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top