22
$\begingroup$

I will be implementing JSON web tokens into my website and have a question about implementing them. I have a choice of using two algorithms, HMAC-SHA256 and ECDSA-SHA256. I have used HMAC-SHA256 in the past for jwt, but now I noticed ECDSA is being added to a lot of jwt libraries. As someone who does not have a strong background in security, I was wondering what the advantages/disadvantages are between these two? Trying to Google HMAC vs ECDSA did not bring up any great results. My areas of concern include:

  • Speed (Since my server will need to sign many tokens, how do they perform?)
  • Security (How do they fair against brute force attacks and rainbow tables? This will probably relate to my first concern.)
  • Stability (Are these algorithms accepted as stable, proven, and reliable?)
$\endgroup$
  • 1
    $\begingroup$ FYI, the draft spec says that HMAC SHA-256 MUST be implemented while ECDSA (or RSA) MAY be implemented. Just wanted to point that out. Poncho's answer is spot on. $\endgroup$ – mikeazo Nov 18 '15 at 19:23
28
$\begingroup$

The distinction is that ECDSA solves a problem that HMAC does not. If you need that problem solved, then you need to do ECDSA rather than HMAC; if you do not, then HMAC works just as well (and is a lot cheaper).

With HMAC, here is what we have: we have an authenticator that has a secret key. It takes a message, and gives that (and the secret key) to the HMAC algorithm, and that generates a tag. We send that tag, along with the message, to the verifier.

The verifier also has the secret key. It takes the received message, and gives that (and the secret key) to the HMAC algorithm, and that generates the tag. It then checks if the computed tag was precisely the same as what it received; if it is, then it knows that the message is precisely as it was when it was originally sent.

With ECDSA, here is what we have. we have an authenticator that has a private key. It takes a message, and gives that (and the secret key) to the ECDSA signing algorithm, and that generates a tag. We send that tag, along with the message, to the verifier.

The verifier also has the public key (which is not the authenticator's private key). It takes the received message and tag, and gives that (and the public key) to the ECDSA verification algorithm, and it checks whether the tag corresponds to the message. If it does, then it knows that the message is precisely as it was when it was originally sent.

So, what's different? With HMAC, both sides share the same key; the verifier could (if it wanted to) generate its own tags to messages of its choice, and those tags would validate just as well. With ECDSA, this doesn't happen; the key that the verifier has (the public key) allows it to check tags, but it does not allow it to generate tags on its own.

So, is this distinction important in your scenario? I don't know enough about what you're doing to say. The question you need to answer is: can you trust the verifier not to generate its own tokens? Can you trust someone who has access to the verifier's keys not to do so? If that is not something you are worried about (possibly because the verifier is the only one who cares about tags generated by a specific set of keys), then HMAC works just fine (and, as I mentioned earlier, is a lot cheaper). If you do care (for example, you distribute the verifier code to lots of people, and you have one set of keys), then it doesn't matter how cheap HMAC is - it doesn't solve your problem - you need to go with something like ECDSA

$\endgroup$
12
$\begingroup$

To add to poncho's answer (since they beat me to it!), there are several advantages to choosing HMAC over ECDSA (or RSA) if you can get away with it:

  • Insanely better performance: signing and verifying is much faster
  • Much simpler implementation: this is important for security (even if you're not the one doing the implementation), since more complexity leads to more opportunity for vulnerabilities.
  • More secure: HMAC has a security proof that holds assuming some basic properties of underlying hash function. HMAC has held up well in the field, too: HMAC-MD5 is still secure, despite some breaks on MD5. ECDSA, meanwhile, requires that the hash function it is used with be "collision resistant" -- a stronger requirement, and less likely to stand the test of time (note that ECDSA with MD5 is broken, while HMAC-MD5 is not). ECDSA could also be broken by various mathematical advances (e.g. in solving the discrete log problem).

That said, if you need the separation between public and private key, ECDSA is a fine choice.

Edit: just to be clear, HMAC-MD5 is still secure, but HMAC-SHA256 is a better choice for new applications.

$\endgroup$
  • $\begingroup$ For web application authentication (JWT), would using HMAC-SHA512 provide more security that using HMAC-SHA256? What are the current recommendations today? Is it true that HMAC-SHA512 is faster to encode / decode than HMAC-SHA256 on 64bit machines? $\endgroup$ – W.M. Dec 9 '17 at 17:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.