How and when do I use HMAC?
I was reading HMAC on wikipedia and I was confused about a few points.
- Where do I use HMAC?
- Why is the key part of the hash?
- Even if someone successfully used a "length-extension attack", how would that be useful to the attacker?
If anyone is curious what i wanted to know was hmac is a way to sign data using a **symmetrical** key. "Its more complex then hashing the message and key together which is not secure" is a bonus.
A friend of mine runs one of the largest "crypto currency" exchanges in the world. His API requires HMAC signing of all api calls with the users Private api key( it would be the "secret" you refer to in your question), which includes the public key in the hash. This is the basic use case, as an additional layer of security for API calls. In the cryptocurrency world, his is the only platform yet to be hacked, despite millions of attempts. HMAC is useful, just make sure you know how to use it. i thought i did, but didn't and paid the price in the form of a devastating API hack.
A message authentication code (MAC) is produced from a message and a secret key by a MAC algorithm. An important property of a MAC is that it is impossible¹ to produce the MAC of a message and a secret key without knowing the secret key. A MAC of the same message produced by a different key looks unrelated. Even knowing the MAC of other messages does not help in computing the MAC of a new message.
An HMAC is a MAC which is based on a hash function. The basic idea is to concatenate the key and the message, and hash them together. Since it is impossible, given a cryptographic hash, to find out what it is the hash of, knowing the hash (or even a collection of such hashes) does not make it possible to find the key. The basic idea doesn't quite work out, in part because of length extension attacks, so the actual HMAC construction is a little more complicated. For more information, browse the hmac tag on Cryptography Stack Exchange, especially Why is H(k||x) not a secure MAC construction?, Is H(k||length||x) a secure MAC construction? and HMAC vs MAC functions. There are other ways to define a MAC, for example MAC algorithms based on block ciphers such as CMAC.
A MAC authenticates a message. If Alice sees a message and a MAC and knows the associated secret key, she can verify that the MAC was produced by a principal that knows the key by doing the MAC computation herself. Therefore, if a message comes with a correct MAC attached, it means this message was seen by a holder of the secret key at some point. A MAC is a signature based on a secret key, providing similar assurances to a signature scheme based on public-key cryptography such as RSA-based schemes where the signature must have been produced by a principal in possession of the private key.
For example, suppose Alice keeps her secret key to herself and only ever uses it to compute MACs of messages that she stores on a cloud server or other unreliable storage media. If she later reads back a message and sees a correct MAC attached to it, she knows that this is one of the messages that she stored in the past.
An HMAC by itself does not provide message integrity. It can be one of the components in a protocol that provides integrity. For example, suppose that Alice stores successive versions of multiple files on an unreliable media, together with their MACs. (Again we assume that only Alice knows the secret key.) If she reads back a file with a correct MAC, she knows that what she read back is some previous version of some file she stored. An attacker in control of the storage media could still return older versions of the file, or a different file. One possible way to provide storage integrity in this scenario would be to include the file name and a version number as part of the data whose MAC is computed; Alice would need to remember the latest version number of each file so as to verify that she is not given stale data. Another way to ensure integrity would be for Alice to remember the MAC of each file (but then a hash would do just as well in this particular scenario).
¹ “Impossible” as in requiring far more computing power than realistically possible.
Can the `hmac` code be shared? It seems confusing to me - It is a hash but can't be shared.
@R11G I don't understand your question. Do note that “it is a hash” is not a useful way to understand HMAC. HMAC is a MAC. The fact that it's based on a hash is an implementation detail. There are other MAC algorithms that have the same security properties but don't use a hash internally, for example CMAC.
@Gilles Sorry. I meant if I log HMAC in my service logs - is it a potential security flaw?
@R11G That depends what it's the HMAC of and what security guarantee you're aiming for. You can't go back from the HMAC to the input without the key. Even with the key, you can only go back by guessing the input and checking it. However, if you see the same HMAC twice, you know it has to be the same input with the same key.
Why `HMAC` does not provide message integrity? Wikipedia and other answers say it does provide message integerity and I think so. "It may be used to simultaneously verify both the data integrity and the authentication of a message, as with any MAC." --- from Wikipedia
@Rick It's a subtlety that's unfortunately often left unsaid. Suppose you receive a message and a putative HMAC of that message from an untrusted source. You calculate the HMAC of the message with the applicable key and see that the correct HMAC is equal to the putative HMAC. What does this prove? It proves that the message was signed by an entity that knows the secret key, i.e. it proves the message's authenticity. But (unless there was only ever one message signed with this particular key) you have no way to know which of the signed messages you have. So this doesn't prove integrity. [cont.]
@Rick A different scenario where the HMAC does prove integrity is if you receive the HMAC value from a _trusted_ source and the message from an untrusted source. In this case, this does prove the integrity of the message. Note that in this scenario, a hash would have worked just as well.