5

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.

Waog
  • 7,127
  • 5
  • 25
  • 37

2 Answers2

3

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.

pedrofb
  • 37,271
  • 5
  • 94
  • 142
  • how can the verification party know, that it didn't got the key from a man in the middle without certificate? – Waog Sep 18 '18 at 20:53
  • 1
    The public key must be previously available in the truststore of the verification party. In such a way that the token is always verified with a trusted public key. How to send this public key or certificate to the verification party is outside the scope of the JWT specification – pedrofb Sep 19 '18 at 07:33
2

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. No standard revocation mechanism: if the signing key has been compromised, how does the verifier become aware of that? With certificates, you have the possibility to revoke certificates, and verifiers use standard OCSP or CRL to verify the revocation status.
  2. 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.)
  3. If the list of public keys is/becomes too big, it is hardly manageable.
  4. 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.
cdan
  • 3,470
  • 13
  • 27
  • Is there any X.509 Extended Key Usage (EKU) extension that can be used to restrict a certificate for JWT signing?. Additionally, do you know of standard methods (if any) to identify these signers, e.g. by using some specific DN attributes or a SAN?. – Jaime Hablutzel Apr 23 '20 at 15:50
  • Don't know any X.509-standard EKU specific to JWT (signing). But using a custom EKU of your own is feasible with flexible PKI (e.g. EJBCA supports custom EKU) and jwt libraries. (Microsoft uses a bunch of vendor-specific EKUs in Windows environments.) Other more "standard" option is a sub-CA dedicated to issuing JWT signer certificates and only that, and JWT verifiers must trust only this sub-CA. Maybe overkill but more compatible with jwt libraries I would expect. – cdan Apr 26 '20 at 00:16
  • Thanks @CyrilDangerville, but note that these approaches would be missing the certificate subject identification. Now, even when it doesn't apply directly to validating certificates used for JWT signing, the best standard based approximation I found is RFC 8705, "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens", that mentions some fields as allowed to identify the certificate subject in the context of OAuth Client Authentication: tls_client_auth_subject_dn, tls_client_auth_san_dns, tls_client_auth_san_uri, tls_client_auth_san_ip, tls_client_auth_san_email. – Jaime Hablutzel Apr 28 '20 at 16:40
  • Not sure I follow when you say the certificate subject would be missing. To clarify, for these approaches to work, every JWT must include a 'x5c' JWS header in the JWT signature with the signer's X.509 certificate as value (the subject and everything, and possibly the certs of intermediate CAs to the trusted CA). The verifier on the other end should require that the x5c is present with a valid certificate (validation process depends on the approach, e.g. in first approach: checking presence of custom EKU for JWT signing). – cdan Apr 29 '20 at 01:08
  • I mean that the certificate verifier usually wants to verify the subject (e.g. by matching it against the expected signer name, e.g. `CN=Token Signer 1`) in the certificate too to get sure that he is receiving an object signed by the party whose signature is expected, otherwise, other entities that received similar certificates from the same CA could generate JWTs with all the properties that you mentioned and impersonate the expected signer. – Jaime Hablutzel Apr 29 '20 at 03:25
  • Not the case in my solutions, there's no "matching [the subject] against the expected signer name" indeed. To clarify, in my solutions (custom EKU or dedicated CA), the goal is to allow verifying that the certificate in the JWT signature is approved (by a trusted CA) specifically for JWT signing; e.g. trusted-CA-issued / not-revoked certificate with custom EKU "JWT signature" (1st approach). This allows to identify *any* valid JWT signer (approved/certified by the CA)...(to be continued) – cdan May 01 '20 at 14:52
  • ... However, it seems now your goal is to filter/authorize a specific one among all subjects with valid (CA-certified) JWT signer certificate. Is that so? – cdan May 01 '20 at 14:52
  • Yes, that's right, given that even a dedicated CA issuing JWT signing certificates with custom EKUs could be generating these certificates for different entities, e.g. departments, organizations, etc. – Jaime Hablutzel May 01 '20 at 16:46