X.509 extensions for verifying JWT

Viewed 2796

I'd like to create a X.509 public key certificate to verify signatures, esp. JWT Tokens.

I'd like to know which properties and extensions properties to set to which values on the certificate to restrict it for JWT verification.

Unfortunately, the specification of X.509 extensions is pretty verbose. So, I'd also be very thankful for a brief overview of available X.509 extensions, properties and their meaning.

2 Answers

JWT signing and validation with asymmetric keys is done using exclusively a key pair, not certificates. It is only needed a public key to validate the token signature.

The public key can be contained in a certificate in order to be sent to the verification party, but this is not really needed, and the recipient is not obliged to perform the validation with respect to any attribute or extension that the X509 certificate may have.

The type of certificate extensions you need to enforce such restriction is... Key Usage and/or Extended Key Usage extensions. For any kind of digital signature, you need at least the Key Usage called... digitalSignature, as specified in RFC 5280. Standard (Extended) Key Usage extensions are all specified in § 4.2.1.3 and 4.2.1.12 of the RFC.

You can always avoid certificates for the sake of simplicity, by maintaining a truststore (a static list) of public keys (or fingerprints if you want to optimize memory/disk usage) on the JWT verifier's side. But this has some limitations, such as:

  1. You have to know in advance all public keys potentially used for JWT signing. This is not always the case. (E.g. in some cases, all you want to know as a verifier is that the key belongs to some trusted organisation's entity and that it has been allowed for signing.)
  2. If the list of public keys is/becomes too big, it is hardly manageable.
  3. If the keys change too often (remember that keys should be renewed regularly), it is hardly manageable.

Therefore, if such limitations affect you, X.509 certificates offer a more scalable and flexible solution, but with an extra layer of complexity of course. With certificates, it works like this:

  • Each JWT issuer has a certificate issued by one or more Certificate Authorities (CA)
  • JWT verifiers should trust these CAs (list of trusted CAs), instead of trusting each JWT issuer's certificate specifically.
  • JWT include the signer's certificate (or certificate chain if you use sub-CAs) in the x5c header parameter of the JWS header as per RFC 7515 (X.509 Certificate Chain), so that the verifier can link the certificate (chain) to one of the trusted CAs.
Related