Home > database >  What is double HMAC verification and how does it work?
What is double HMAC verification and how does it work?

Time:05-02

From the Mega Security Whitepaper:

The API does not store the unhashed Authentication Key sent by the user. It only stores the Hashed Authentication Key to prevent “pass-the-hash” attacks (wherein the scenario of a leaked database, an attacker would just pass the Hashed Authentication Key to get authenticated and carry out actions as the real user). The server always hashes the Authentication Key received from the client which prevents this attack vector.

If the Hashed Authentication Key does not match the result in the database, the API responds with a negative response to indicate failure. The API side avoids timing attacks here by using Double HMAC Verification (https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/).

Unfortunately the link is dead and a google search often points back to the same source. Can you please explain how double hmac verification works when you need the original key to verify the signature? Thank you

CodePudding user response:

That URL has been archived by Wayback Machine so you can still read the full blog post: http://web.archive.org/web/20160203044316/https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/

The post contains a C# code snippet that demonstrates how to perform a double HMAC verification. In the end is pretty easy, just as the name "double HMAC" indicates it performs an HMAC two times, using the same HMAC-key.

public void validateHMACSHA256(byte[]receivedHMAC, byte[]message, byte[]key) {
    HashAlgorithm hashAlgorithm = new HMACSHA256(key);

    // size and algorithm choice are not secret; no weakness in failing fast here.
    if (receivedHMAC.Length != hashAlgorithm.HashSize / 8) {
        Throw new CryptographicException("HMAC verification failure.");
    }
    byte[]calculatedHMAC = hashAlgorithm.ComputeHash(message);
    // Now we HMAC both values again before comparing to randomize byte order.
    // These two lines are all that is required to prevent many existing implementations
    // vulnerable to adaptive chosen ciphertext attacks using the timing side channel.
    receivedHMAC = hashAlgorithm.ComputeHash(receivedHMAC);
    calculatedHMAC = hashAlgorithm.ComputeHash(calculatedHMAC);

    for (int i = 0; i < calculatedHMAC.Length; i  ) {
        if (receivedHMAC[i] != calculatedHMAC[i]) {
            throw new CryptographicException("HMAC verification failure.");
        }
    }
}
  • Related