Signature verification Using JWKS endpoint in WSO2 Identity Server
JWT tokens have a signature to prove their legitimacy to the client or resource servers. In the testing environments, it is easy to validate JWT as we have access to the keystore where we keep the public-private key pair. In the production environments, we need our consumers to validate our tokens before proceeding. Thus we need to have a way to convey our public key to the third party who is going to use that token.
As a solution to the above conundrum JWKS endpoint was introduced. In this article, we will see what is JWKS endpoint and how we can validate our tokens from it. We will also see an example application that makes use of JWKS endpoint directly to validate the tokens
What is JWKS endpoint?
The JSON Web Key Set (JWKS) endpoint is a read-only endpoint that contains the public keys’ information in the JWKS format. The public keys are the counterpart of private keys which is used to sign the tokens.
according to spec https://tools.ietf.org/html/rfc7517
JSON Web Key: A JWK is a JSON object that represents a cryptographic key.The members of the object represent properties of the key, including its value
JWKS: A JWK Set is a JSON object that represents a set of JWKs. The JSON object MUST have a "keys" member, with its value being an array of JWKs
In simple terms, JWKS has arrays of keysets. Each keyset can be used to create a public key
eg:
above is sample keyset for RSA public key
Here
kty → identifies the cryptographic algorithm family used with the key, such as “RSA” or “EC”kid → (key ID) parameter is used to match a specific key. This is used, for instance, to choose among a set of keys within a JWK Set during key rollover. The structure of the “kid” value is unspecified. When “kid” values are used within a JWK Set, different keys within the JWK Set SHOULD use distinct “kid” valuesuse → parameter identifies the intended use of the public key. It can be either “sig” (signature) or “enc” (encryption).alg → parameter identifies the algorithm intended for use with the key.eg in RSA, we can have RSA256 or RSA512 e,n → are related to RSA algorithms. n is the modulus and e is the exponent. EC type will have different parameters
How does the JWT signature work?
The JWT will have the following components
- Header
- Payload/body
- signature
with the typical format like
xxxx.yyyy.zzzz
ie
Base64URLencode(Header).Base64URLencode(body).Base64URLencode(signature)
The signature will have the following pseudo-code:
RSASHA256(Base64URLencode(Header).Base64URLencode(body), private key)
How to validate using JWKS endpoint?
validation will happen in the following steps
- Retrieve the JWKS from JWKS endpoint
- Get JWT and decode it.
- Grab the
kid
property from the header of the decoded JWT. - Search the key with the matching
kid
property in retrieve keysets. - Build a (public)certificate using the corresponding keyset
- Use the certificate to verify the JWT’s signature.
JWKS endpoint in WSO2 Identity server
Each tenant in the Identity server has its own JWKS endpoint. In each endpoints, we can have multiple keysets correspond to
- different keys in the keystore
- different algorithm in the identity.xml → we can set three different algorithms for the following JWTs: Access token, Id token and Userinfo token in identity.xml. Each algorithm will have their own kid to identify the keyset easily. Currently, we only support RSA based algorithms.
Use the following URL
- For super tenant go to https://<is-server-url>/oauth2/jwks
- For tenant go to https://<is-server-url>/t/<tenant-name>/oauth2/jwks Eg: for foo.com : https://localhost:9443/t/foo.com/oauth2/jwks
The explanation behind these 4 key sets:
- Earlier when signing with the same key but using different algorithms like RS256, RS348 and RS512 we had the generated the same kid for all the keysets but now we have one entry with normal “kid” and one with “algo” appended to“kid” → kid_algo
eg: here we have one kid with
NTAxZmMxNDMyZDg3MTU1ZGM0MzEzODJhZWI4NDNlZDU1OGFkNjFiMQ
and one with “algo” appended
NTAxZmMxNDMyZDg3MTU1ZGM0MzEzODJhZWI4NDNlZDU1OGFkNjFiMQ_RS256
- Since we only configured one signing algorithm for all the types of JWTs (Access token, Id token and Userinfo token) in identity.xml we only have one additional kid along with the old kid. If we had different algorithms there would be different keysets for each one them along with the old kid.
eg: currently we will have 2 keysets one with an old kid and one with a new kid
- Next, we had two different key entries in the keystore. Thus we have two times the key sets of si ngle key entry.
eg: here it will be 2* 2 different keys = 4 different keysets
- the following will be the pseudo-code for this logic
no of keysets= no of key entries* (1 + different signing alogrithms)
here 1 is for old kid generation method.
Example application to validate token using JWKS endpoint
This application will retrieve the JWKS from the endpoint and validate the JWT directly.
Please provide:
- Access token
- JWKS endpoint
Output: This application will print the claims if the verification passed
if you face any SSL handshake failure please follow this link[1]. If you face any connection timeout problem increase the timeout in “DefaultResourceRetriever”
Resources