There is a set of parties, each of whom have a public/private key. I have the public key for each of them.

These parties will send me JWTs signed with their private key. I do not know which party sent the JWT, so I need to check the JWT. If the signature matches for public key #1, I know it came from party #1.

I want a way to securely identify the party who sent the JWT.

The easiest but slowest way to do this is to check each public key until it matches.

The solution I have in mind involves matching the public key to the iss field of the JWT. I can sneak a look in the JWT, without verifying the signature, extract the iss claim, use that to decide which public key to use, and then use that to verify the signature.

I can't see any security holes in this approach, but needing two passes feels wrong. Is there a standard way to do this?


There are headers explicitly defined for this sort of thing in the JOSE standards. You can use

  • JWK which is the actual public key -- you just have to make sure they match what you have locally.
  • KID which is just an arbitrary identifier of the key -- you could use a thumbprint of the public key and just do a local lookup.

In the first case you want to be careful and not just rely on the presented key, but rather use it to look up a local key.

| improve this answer | |
  • Thanks, I found JWK and jku, exactly what I was looking for. – Joe Feb 16 '17 at 17:14

These parties will send me JWTs signed with their public key.

JWTs are signed by private keys or are HMAC'ed using a shared key. I hope it's a typo.

Also, JWT libraries exists in almost all languages/frameworks, you should be better off using one of those as they are properly vetted.

Having said that, your approach looks fine. There are various scenarios:

  • There has been no tampering with the iss field. In such a case you'll look up the corresponding public key in O(1) time and should be able to verify the token.
  • An MITM attacker changes the iss field, in which case you'll load a incorrect key or no key will be found depending on if the iss field is valid or not. The signature will not verify in both cases and you should discard the JWT at that point.
  • Also discard the JWT token if the alg param is set to none. While its a proper JWT construct, its insecure as its not signed. https://tools.ietf.org/html/rfc7519#section-6.1
  • Also discard any trick in which JWT token has an embedded public key that you should be using to verify the token. An attacker can replace the sign and replace the public key such that the verification succeeds. The public key (or symmetric key in case of HMAC) should always be looked up from receiver's data store.
| improve this answer | |
  • Thanks for your answer. Yes, that public/private was a typo. The jku header parameter looks like what I'm looking for, and I hope to find it's supported in standard libraries. – Joe Jan 17 '17 at 12:12

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.