X.509 extensions for verifying JWT - certificate

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.

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:
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.
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.)
If the list of public keys is/becomes too big, it is hardly manageable.
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

Assymetric signing algorithms for JWT signing

JWT noob here, so sorry if this is a stupid question: Is it possible to sign JWTs with assymetric keys/certificates/etc?
If I understand JWTs right, the idea is that the client can authenticate to the server with them because they contain a signature the server can check.
All the examples I've seen online rely on the same secret key for creating and verifying the JWT.
Now, if I wanted to issue JWTs for different servers and did it like that, I'd have to give them my secret key (probably one for each server), and they'd be able to issue JWTs with it. I might not want to allow that. Also each server could only verify JWTs that were created specifically for it or one with the same key.
On the other hand, I do know that things can be signed with assynchronous algorithms in such a way that you can verify the signature with a public key, but sign stuff only with the private key.
That would solve the problem, because each server that wants to accept JWTs my server signed only has to download my public key. Does such a thing exist in JWT?
I think you mean an asymmetric algorithm, not an asynchronous algorithm.
The short answer is yes - you can use an asymmetric algorithm like RS512 to sign a token with a private key and then validate it with the matching public key. This way you don't have to share the secret outside of the service that signs the token.
Note that different libraries may support different algorithms, so make sure to check which algorithms the library you use supports. JWT.io has a pretty comprehensive listing of which libraries support which algorithms.

How Verify X.509 Signature?

X.509 certificate has signature value.
I want to verify the signature in client certificate with public key of root CA or intermediate CA.
I know the information of both of them. But I don't know what messages needed.
I want to ask what's the messages needed to generate the signature value?
It only need Issuer information or Subject Name by hex? or is the issuer arbitrary when generating a certificate?
Verifying the signature is not sufficient, you need to validate the certificate chain and all of the associated policy constraints. In Windows / C you would use CertGetCertificateChain(https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetcertificatechain), but each platform has its own approach to this problem. Its far more complicated than most realize (https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf) so please stick to platform APIs for this validation.

How can JWT be verified outside the authorization server

Recently, I'm trying to implement an OAuth2.0 server using JSON Web Token (JWT) as access token. I'm very confused about the self-contained feature of JWT. I notice that JWT can be verified anywhere, not mandatorily in authorization server because it is self-contained. How does this feature work? What claims should be included in JWT in order to realize self-contained feature?
Another question is that, if JWT is stateless, it means the server should not store the JWT. Then how is the JWT verified? Can't it be easily forged?
I'm the rookie in this field, I wish someone could help me out:)
JWT contains claims that can be signed, encrypted or both.
These operations are performed using cryptographic keys. Keys can be symmetric (e.g. octet keys) are Asymmetric (e.g. private/public key pairs such as RSA or EC keys).
When you want to verify a JWT (i.e. a JWS), you have to perform the following steps:
Check the header (algorithm is supported, critical claims are in the payload and their value are understood).
Check the claims (especially exp, iat, nbf, aud).
Check the signature.
To check the signature, you need the key and, depending on the algorithm, this key can be
The symmetric key
The public key if asymmetric
When you want to allow third party applications to verify your JWT, you will use asymmetric keys and share the public key with the third parties.
As public keys cannot be used to sign, third parties cannot forge a valid token with custom claims.
The way you share the keys is up to you. The common way is to provide an URL where applications will retrieve them (e.g. Google keys at https://www.googleapis.com/oauth2/v3/certs).

Public and private keys governance in JWT

I'm trying to better understand JWT and how to properly use it.
In common JWT use cases (like JWT-based authentication or JWT access token in oauth), does it make sense to verify a JWT token client-side? In particular, I'm asking this to better understand the requirements on the public and private keys that are involved in the JWT signing and encryption. If the clients never need to verify the JWT signature than the server does not need to make its public key available. If this is true, I don't even need a full blown X.509 certificate: a bare public/private key pair or a self signed cert would suffice, right?
So all this boils down to the question: what is the right way to deal with asymmetric keys used in JWT? Do I need a public key infrastructure or is a simple private/public key pair enough?
I understand that JWT specs do not cover this: yet I'm curious to know what the common practices are in real JWT usage.
Of course this question has nothing to do with the certs involved in https: I'm just talking about the keys used in JWT signature and encryption.
does it make sense to verify a JWT token client-side?
It makes sense if you use the token payload data to perform an operation in client side, and you need to trust the token. If you use the token for authenticate in a server, then let the server verify the signature.
if this is true, I don't even need a full blown X.509 certificate: a bare public/private key pair or a self signed cert would suffice, right?
Do I need a public key infrastructure or is a simple private/public key pair enough?
You can use either a trusted certificate, a self-signed certificate or simply a RSA keypair. Usually is used an autogenerated keypair. But if you do not plan to verify the signature on client, you can just use a HMAC symmetric key (not assymetric

For signing JSON web token, should I re-use the https domain certificate keys or create a new key pair

I am implementing a REST service which has RESTful authentication using jwt based on suggestions from this and this answers.
In constructing the JWT I have decided to sign it using an rsa public private pair rather than hmac for the obvious benefit of being able to keep my signing key fully private because I don't trust the clients that I will need to share the validation key with.
My question is, since normal https server certificates already use rsa keys, would it be acceptable to use that same key pair to sign a JWT token? One advantage I can see is that I will not have to maintain two certificates and mechanisms for sharing the public key with the client are already well established.
PS In case I sign the JWT with a new specific key pair, what is the best way of sending the public key to the client for use in verifying the token?