Question

We are using the below code to generate a HMac hash against a sensitive value in C#

public string GenerateHMac(string key, string message)
{
    var decodedKey = Convert.FromBase64String(key);

    var hasher = new HMACSHA256(decodedKey);

    var messageBytes = Encoding.Default.GetBytes(message);

    var hash = hasher.ComputeHash(messageBytes);

    return Convert.ToBase64String(hash);
}

The key passed in is a 256 bit base 64 encoded string. A question was raised as to whether we should be using HMACSHA256, HMACSHA384 or HMACSHA512 to hash the value.

  • What are the advantages to using HMACSHA512 over HMACSHA256?
  • Is it significantly more secure?
  • Are there dramatic performance implications when using a longer key?

As a side note; does the decodedKey value I am passing into the constructor need to be a 512 bit key if I use HMACSHA512?

Was it helpful?

Solution

TL;DR: use HMAC-SHA512 for optimum speed, security and OK compatibility. HMAC-SHA256 is also very secure and could be useful on CPU's with 32 bit operations. Moreover, it is accelerated on many of the latest CPU's.


To see the strength of the hash methods themselves, please take a look at the keylength.com website. You will see that even SHA-256 has quite a large security margin.

What's more, the HMAC algorithm is pretty much oblivious to attacks on the underlying hash algorithm. HMAC is impervious to the birthday problem which halves the key strength to half of the hash output. It doesn't apply simply because the adversary doesn't hold the secret key and can therefore not try to create collisions. This is why even HMAC-SHA1 is pretty secure.


Now the speed of the hash depends on the execution environment. But in general you can make the following assumptions:

  1. SHA-1 is generally faster than any SHA-2 implementation on the same platform;
  2. SHA-512 is faster than SHA-256 on 64 bit machines (as they use 64 bit arithmetic internally);
  3. SHA-256 is faster than SHA-512 on 8, 16 and 32 bit machines.

Use SHA-1 if you are expecting compatibility issues. Otherwise you may as well go for SHA-512 (and cut the result to a reasonable number of bits). The internal state and higher security of SHA-512 may be a slight advantage. I've ran into issues with customers not accepting any form of SHA-1 because of general issues with the algorithm; in other words, the fact that it is not secure in general may hinder acceptance.


Note that SHA-384 and the less well known SHA-512/256 and SHA-512/224 hash methods are a special form of SHA-512, cut to 384, 256 and 224 bits output. So the speed of these algorithms is identical. The only difference apart from the output size is that these special forms use different initial values internally. Otherwise SHA-512 cut to 384 bit is as secure and as fast as SHA-512/384. You should however use SHA-384 to remain compatible - if you require that particular output size.

SHA-384 and SHA-512/256 and SHA-512/224 use different initial values so that the output of either of them is different from SHA-512 and each other; a feature called domain separation. The domain separation makes it impossible to use attack or (partially) predict hash results of the other, related hash functions.


The input key size is not dependent on the underlying hash function. The key is first XOR-masked and then hashed by the underlying hash function; hash algorithms can take virtually unlimited amounts of data as input.

It is advisable to use a key size that is at least the size of the hash method used, otherwise you may degrade the security margin provided by the HMAC method. There may be a minor performance penalty if the key size forces the hash algorithm to hash multiple blocks.


You could also use the (upcoming) SHA-3 standard in the sense that it would be secure. HMAC-SHA-3 currently doesn't make too much sense though. HMAC is actually overkill for SHA-3 (Keccak); SHA-3 should be secure even without the HMAC construct. By now KMAC has been standardized as MAC construct for SHA-3.

The SHA-2 constructs have - somewhat surprisingly - shown pretty good resistance against crypt-analysis during the SHA-3 competition. So there is no pressing need to upgrade to KMAC / SHA-3.

OTHER TIPS

I don't think you need to worry about security advantages, HmacSha1 is still thought to be secure even and the security should be thought of as relative to the key length. Sha256 vs Sha512 performance will depend on implementation, platform, etc, you'll have to test yourself. And the key lengths you provide to HMAC are independent of the hash algorithm, see pseudocode.

HMAC invokes the hash algorithm twice vs. SHA3 does not require HMAC construction for keyed hashing so dual invocation is easily avoidable. As a result, SHA3 beats HMAC-SHA2 in performance and HMAC-SHA1 in security (best of both worlds).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top