Application Security #4: What do jwk keypairs look like? Have I found something sensitive?
What does keypairs look like? What does it mean? Where to find it? How to generate it?
Whenever I perform penetration testing on an application which uses bearer token authentication based on JWT token, I used to keep Googling what each key parameter means in the JWT header section. Likewise, when I come across jwk keypair files or jwk keypairs set in some paths on the website, I always have to make a decision. Do these keypairs serve as just public information or it is unintended sensitive data disclosure concerning keypairs?
So, this post is a note for me and for anyone who might be interested.
The signing and/or encryption keys are the lifeblood of JWT tokens be it symmetric or asymmetric algorithm. if you get your hands on the correct key pairs, you essentially own the whole authentication/session management mechanism of the web application. That is why it is important to decide if the keypair you are looking at is just a public key or it is something more that you can use to forge JWT tokens.
This post contains the following sections:
- Glossary for jwk, jwks etc
- What does jwk Public Keypair look like?
- What does jwk Public and Private Keypair look like?
- What does each key parameter stand for?
- Where to find jwk keypairs on the websites?
- How can you generate your own jwk keypairs for observations?
Glossary for jwk, jwks etc
- JWK: Java Web Key
- JWKS: Java Web Key Set or a collection of JWK
- JWT: Java Web Token
What does jwk public Keypair look like?
The following is a public key set which we normally come across. All of this are public information, nothing sensitive.
{
"kty": "RSA",
"e": "AQAB",
"kid": "rsatest1",
"n": "p95A77RxUg622xCoYZyFOCfHSh_3dKdH7axV49C4OfLaS12p9zb35pokwfpcYQAKbZJXaxnKkGWMCuHTv_DdVQ"
}
Refer to What does each key parameter stand for? below for what each key parameter means.
What does jwk Public and Private Keypair look like?
This is very unlikely but if you come across the following kind of key set, you have struck a jackpot. This is a public and private key set which obviously contains private keypair information or secrets such as secret keys and/or prime factors: d,p,q,qi,u.
{
"p": "5R4S4fuU_nWryNtMc3gJE88XQgfG8_D4Jfduk4bKEwc",
"kty": "RSA",
"q": "u5B0dKFPccSHQHUQgz35Ee-rCer_yePDSmskIrX16cM",
"d": "I9H8uEmgPrrOEQvKal3MXZG7aFlO4_EIG7LA9yZkEVUkjo97ZNQkiEjOJd3IwoZ_5D-XmvrZxjfDxBPxv7tPxw",
"e": "AQAB",
"kid": "rsatest1",
"qi": "sJ3xIr31NHXvpd3vRLiUOz4rYBu3Ldiktq0Qv7B-I-4",
"dp": "WjUUBCt0hxc3UnadTB0nncf8hT_goizu1qvrumPobcM",
"dq": "eNfpL_t-I95rBaxmpygWgOfZWtp9UqXb_OZqsbJqbeE",
"n": "p95A77RxUg622xCoYZyFOCfHSh_3dKdH7axV49C4OfLaS12p9zb35pokwfpcYQAKbZJXaxnKkGWMCuHTv_DdVQ"
}
Refer to What does each key parameter stand for? below for what each key parameter means.
What does each key parameter stand for?
The following are key names and what they are for (alphabetically sorted by key names)
- alg: algorithm. e.g. RS256, ES256, PS256
- crv: Specifies elliptic curve being used. e.g. P-256, P-384
- d: RSA secret exponent (modular inverse of “e” modulo (p-1)(q-1)).
- e: RSA public exponent.
- kid: Key ID.
- kty : Key type or type of cryptographic key used. e.g. RSA, EC, oct.
- n: RSA public modulus (the product of two prime numbers).
- p: First RSA secret prime
- q: The other RSA secret prime (condition — “p” is less than “q”).
- qi: The modular multiplicative inverse of “q” modulo “p”.
- u: Multiplicative inverse of “p” modulo “q”.
- use: use or usage. “enc” for encryption, “sig” for signature.
- x: The base64-encoded x-coordinate of a point on the elliptic curve.
- x5c: The certificate chain. A JSON array of base64-encoded DERs
- x5t: The thumbprint for the certificate. (SHA-1 hash)
- y: The base64-encoded y-coordinate of a point on the elliptic curve.
Where to find jwk keypairs on the websites?
By design, the keypairs are usually announced by the websites and can be found typically in the following path:
- https://<domain>/.well-known/openid-configuration
- https://<domain>/.well-known/jwks.json
You might come across the actual jwk keypairs file from other means of exploits such as Path Traversal attack or command injection etc. For those cases, you can use keytool and openssl to observe if the key contains private key materials. But that is a topic for another day.
How can you generate your own jwk keypairs for observations?
First of all, it is best not to generate keypairs online for actual production use for your application. Always use local tools or local command line based means of keypair generation to safeguard your keys. The following are just for testing and observations.
- This website is handy for generation multiple types of jwk keypair: https://mkjwk.org/
- If you use Burp Suite Pro, you can leverage JWT Editor Burp Extension which can generate both symmetric, asymmetric keypairs and is exportable to both jwk and pem format. I am not sure how long the link will be valid but here it is https://portswigger.net/bappstore/26aaa5ded2f74beea19e2ed8345a93dd
Thanks for reading!