Understanding JWKS: JSON Web Key Set Explained

Latest

Auth & identity

February 29, 2024

Author: Isaac Ejeh

When it comes to safeguarding sensitive resources such as APIs, M2M applications, and other software workloads, cryptographic keys are a more secure option than traditional cookies or API keys.

Unlike symmetric cryptography which employs a single secret key for both data encryption and decryption, public-key (asymmetric) cryptography leverages a pair of mathematically related keys that are generated by a specific cryptographic algorithm. These key pairs consist of a publicly accessible key and a corresponding private key, which remains strictly confidential.

As such, any authorization server can use private keys to sign tokens, but only the holder of the corresponding (paired) public key can verify the signature’s authenticity. The security of this asymmetric cryptographic system rests on the secrecy and protection of the private key, which must not be disclosed or leaked to any unauthorized parties.

More specifically, cryptographic keys are commonly used in modern applications to sign and verify the authenticity of identity and access tokens (JWTs) during the stateless authentication and authorization of human users or machines.

JSON Web Tokens (JWTs) are access tokens used to identify authenticated users and determine their appropriate level of privileges or permissions. However, to validate the integrity of a JWT and the encoded data, we have to leverage a pair of public and private cryptographic keys. This is where JSON Web Key Set (JWKS) comes into play.

As defined by the IETF RFC7517 standard, JSON Web Key (JWK) is a JSON data structure that provides the standardized format for representing public and private cryptographic keys. JSON Web Key Set (JWKS), on the other hand, serves as a secure repository or vault that stores the collection of public keys necessary for verifying and decoding specific JWTs.

In this article, we’ll explore the role of JSON Web Key Sets (JWKSs) in signing and managing JWTs for secure sessions and API communication. We’ll clarify the distinction between JWK and JWKS, unpack the JWKS data structure, and illustrate their practical application using real-world examples.

JWK vs JWKS

Imagine a secure building that has multiple doors, each protected by a lock that requires a unique key to open. In this analogy, each JWK would represent the specific key for a particular door/lock, while the JWKS is analogous to the keyring that holds all the keys used in the building.

Just as you wouldn’t hand over the entire keyring to every visitor, JWKS ensures that only authorized clients access the specific JWK necessary for their designated operations within a system.

A JWK is a JSON object representing a single cryptographic key. It holds vital identification data, such as the key type, key identifier, the cryptographic algorithm used to sign it, usage restrictions,  and other additional details for verifying a JWT signature and decoding it to plaintext. Think of a JWK as the individual key in our building example, but only the public key value is accessible within the JWK, ensuring that the private key stays confidential and secure.

A JWKS is also a JSON object notation, but it contains an array or collection of individual JWK objects. Put simply, JWKS is a set of public keys that can be used to verify the JWTs issued by a specific authorization server.

Think of JWKS as the keyring that holds all the public keys used within a system. It allows clients to retrieve the necessary keys for validating JWTs depending on their specific function or business domain.

Structure of a JWKS

The structure of a JWK is defined by a set of key-value pairs, where each pair plays a specific role in representing the cryptographic key. Each JWK, whether it’s an individual key or part of a JSON Web Key Set (JWKS), contains various properties depending on the cryptographic algorithm that has been used to sign the key.

Some common characteristics of a JSON Web Key (JWK) include:

  1. Key type (“kty”): This attribute specifies the particular family of cryptographic algorithms used to sign the key. Popular values include “RSA” for RSA keys, “EC” for Elliptic Curve keys, or HMAC.
  2. Signature algorithm (“alg”): This identifies the particular algorithm that has been used to sign the key. For example, RS256, ES256, PS256, etc.
  3. Key operations (“key_ops”): This attribute defines the operations that a key is allowed to perform. It’s an array of strings specifying which cryptographic operations the key is intended to be used for.
  4. Key identifier (“kid”): This is the unique identifier for a key. It aids in key matching and retrieval within a JWKS.
  5. Key use (“use”): The “use” property indicates the intended use or purpose of the key, whether it’s for signing (“sig”), wrapping other keys (“wrap”), or encryption (“enc”).
  6. X.509 certificate chain (“X5C”): This optional attribute specifies the chain of PKI certificates used to sign the JWT. The x5c and x5t parameters are especially relevant in scenarios where public key infrastructure (PKI) is employed for secure communication, and they help convey information about the X.509 certificate associated with a key.
  7. X.509 certificate thumbprint (“X5t”): This optional property contains the SHA-1 thumbprint of the X.509 certificate used to sign the token. The thumbprint is a unique identifier calculated from the certificate’s data.
  8. Additional properties: Depending on the key type (“kty”) and signature algorithm (“alg”), additional properties can be found in a JWK. For instance, an RSA key-type JWK would have “n” (public key modulus) and “e” (exponent) parameters, while EC keys typically contain the “crv” (curve type) property and “x” and “y” coordinates.

Structure of a JWK signed using an RSA algorithm

Structure of a JWK signed using an EC algorithm

What is a JWK endpoint?

A JWKS endpoint is a designated HTTPS endpoint typically exposed at a well-known location on the authorization server (or any server managing the cryptographic keys), such as “https://<server_domain>/.well-known/jwks.json”.

This endpoint is a read-only URL that responds to GET requests by returning JWKSs as JSON objects. The primary purpose of a JWKS endpoint is to provide applications with the public keys necessary to verify the signatures of JWTs issued by an authorization server.

Identity providers like Stytch typically offer JWKS endpoints that allow your servers to retrieve JWKSs which can be used to verify the authenticity of JWTs issued by our authorization server at any time.

Cryptographic signature algorithms

Signing algorithms are integral to safeguarding the authenticity and integrity of JWKs. They generate digital signatures that verify the sender’s identity and ensure the exchanged data remains unaltered during transmission.

Common signature algorithms:

  • RS256: This is the most widely used signature algorithm when it comes to signing JWTs. It relies on the RSA public-key cryptosystem, where a pair of public and private keys is used for encryption and decryption.
  • RS384 and RS512: These are variations of RS256 that employ stronger SHA hashes, specifically SHA-384 and SHA-512, respectively. However, increasing the hash length comes at the cost of higher computational overhead.
  • PS256: PS256, or RSA signature with SHA-256 and MGF1 padding, is another RSA-based algorithm that combines RSA with SHA-256 hashing. Security-wise, PS256 is generally less recommended than RS256 due to potential vulnerabilities associated with this padding mechanism.
  • HS256: This is a symmetric signature algorithm that combines HMAC with the SHA-256 hash function. Unlike asymmetric algorithms like RS256, HS256 uses a single shared secret key for both signing and verifying signatures.
  • ES256, ES384, ES512: These algorithms utilize the elliptic curve digital signature algorithm (ECDSA) with different curve sizes (P-256, P-384, P-521) respectively. ECDSA offers several advantages over RSA, including smaller key sizes, faster signing and verification operations, and comparable security levels.

When selecting a signature algorithm, factors such as security requirements, computational efficiency, compatibility with existing systems, and the size of the keys need to be considered. Each algorithm has its strengths and weaknesses, and your choice should be based on the unique needs and constraints of your architecture.

Example applications of JWKS

Authentication and social logins

When a user attempts to log into an application using a social login, the application must request authentication of the user’s identity from the specific social media platform, whether it’s Facebook, GitHub, Google, etc.

The social media platform responds to the application by sending a login token that has been encrypted with its private key. Upon receiving the login token, the app has to verify its authenticity using a public key obtained from the social media platform’s JWK endpoint. If the decryption is successful, it confirms that the token was indeed encrypted by the social media platform’s private key, ensuring the user’s authenticity.

The private key is securely stored on the social media platform’s servers, while the public key is shared openly for verifying information encrypted by the private key. This setup prevents imposters from creating valid login tokens, as they lack access to the social media platform’s private key, making it exceedingly difficult to produce a token that can be successfully verified with the public key.

Securing backend communication

Whenever you use your favorite app, it communicates with various servers and services behind the scenes. Mobile and web apps constantly talk to their backend servers, and JWKS ensures communication stays private.

The backend server, which houses sensitive data and user information, employs a pair of cryptographic keys: a private key and a corresponding public key. The private key is securely retained within the backend server, while the public key is designated for sharing.

JWKS acts as a secret tunnel, allowing the backend to securely share its public key with the frontend. This verifies that only authorized requests get through, protecting the app’s data and user information from unauthorized access. JWKS can also be used to secure communication in both internal and open APIs, and even a microservices architecture.

Aside: with a powerful suite of API primitives for authentication, Stytch enables developers to use JWTs and JWKS seamlessly to build their login flows, manage their user sessions, and authenticate M2M clients. Learn more.

Why JWKS?

Key rotation and revocation

Using JWKS eliminates the need to manually update keys across all connected clients or systems. When a key needs to be rotated, the authorization server updates the new key to the JWKS endpoint and marks the old one as inactive. In this way, resource servers can automatically retrieve the new public key when next they need to verify a token.

On the other hand, rotating keys at specific intervals help to reduce an application’s attack surface area in the event of a leakage. If one key is compromised, the attacker’s access is limited to the set time-to-live period, thereby minimizing the impact of the breach.

Scalable key management

As your application scales, JWKS can seamlessly accommodate the growing number of keys and clients, eliminating the need for significant infrastructure changes. JWKS simplifies key administration by allowing you to store multiple public keys for various purposes in a centralized location.

Going back to our keyring analogy, each JWK can serve a specific purpose, just like the different keys on a physical keyring. Whenever a server needs to verify a JWT, it can retrieve the appropriate public key from the JWKS endpoint based on the intended use. This eliminates the need for maintaining separate key management systems, reducing complexity and improving security.

Managing JWKS via Stytch

Within Stytch, all JWTs, whether they are session JWTs or machine-to-machine (M2M) JWTs, are signed with a specific JWKS associated with your Stytch project. These signatures are available at a project-specific URL and can be validated locally using any Stytch client library or with any library that supports JWT signature validation.

If you’re using your own JWT validation library, many have built-in support for JWKS rotation. In such cases, you’ll need to supply our Get JWKS endpoint from which the library can fetch the updated JWKS.

To get started, check out our documentation and sign up for a developer account. If you have any questions, please don’t hesitate to contact us at support@stytch.com.

SHARE

Get started with Stytch