We have released a major update to our JWT.io website and the JWT Debugger extension based on it. Among the new features, there are new signing algorithms, improved public-key handling, human-readable timestamps, and even Firefox support for the extension! In this post, we will go over these new features.
JWT.io and the JWT Debugger extension
JSON Web Tokens (JWTs) are a convenient way to exchange claims between parties. The key features of JWTs are their simple format (Base64-encoded JSON) and the use of signatures and/or encryption. JWT.io provides a convenient way to debug and inspect JSON Web Tokens (JWTs), along with an introduction to some of the key concepts behind them. It also provides a list of libraries and frameworks that can be used with them in many different programming languages.
The JWT Debugger extension is the Web Extension version of JWT.io. The debugger has the same features as the website but can be used offline. It also provides additional features like automatic inspection of web storage and cookies to easily find and edit JWTs in websites!
New versions of JWT.io and the JWT Debugger extension have been released. Let's go over the changes.
New Signing Algorithms
For a long time, JWT.io and the JWT Debugger extension only supported the two most popular algorithms: HS256 and RS256. HS256 is an HMAC-based algorithm that relies on a shared secret between parties to produce and verify signatures. On the other hand, RS256 is an RSA-based algorithm, relying on public and private key pairs to sign and verify signatures. The advantages of RS256 are clear: signatures can only be produced by the private-key holder, while verification can be performed by anyone holding the public key. However, the complexity of the implementation for RS256 can make HS256 signatures better for certain use cases (embedded, small devices, etc.).
The new version of JWT.io and the extensions support many more algorithms:
These are variants of HS256. HMAC signatures rely on a hash function to produce and verify the signature. In the case of HS256, the hash function is SHA-256. For the other two, the hash functions are SHA-384 and SHA-512. For certain use cases, SHA-512 exhibits better performance than the other two. Security wise, none of these hash functions has been broken.
Much like the HMAC counterparts, RSA signatures also rely on a hash function to produce and verify a signature. The same thing changes between RS256, RS384, and RS512.
PS256/384 use a different type of signature (RSA-PSS) that also relies on the RSA algorithm as the baseline. In particular, it uses an encoding method that relies on a random salt value. This produces probabilistic rather than deterministic signatures. It is considered stronger than RS256/384/512 signatures as long as the random salt is truly random. In case the salt is not truly random, it provides the same level of strength as the baseline RSA algorithm
These algorithms rely on the elliptic-curve digital signing algorithm (ECDSA) rather than RSA. The main advantage of ECDSA is that keys can be smaller for a similar level of cryptographic strength. A 256-bit ECDSA key provides a cryptographic strength similar to a 3248-bit RSA key. This makes ECDSA keys better for certain hardware limited devices.
If you are interested in a detailed rundown of JWT signing algorithms, don't forget to check our JWT Handbook. Chapter 7 goes over all signing algorithms in detail.
JWTs also support setting the
alg claim to
none. This means that the JWT is not signed. Unfortunately, this has resulted in critical vulnerabilities in JSON Web Token libraries. For this reason, JWT.io and the JWT Debugger extensions now consider
alg: "none" tokens always invalid.
Automatic Public-Key Download
Another interesting feature that has been added is automatic public key downloads. Public-key algorithms, such as RSA, RSA-PSS, and ECDSA, rely on public-keys to verify signatures. Public-keys, like their name implies, can be safely shared without compromising the security of the signature. For this reason, it is not uncommon for JWT public-keys to be available either embedded in the token itself, or in a public URL.
JWT.io and the JWT Debugger extensions now attempt to get public keys in different ways according to the claims embedded in the token.
If the token contains both the
kid claims, JWT.io will attempt to download the token from a specially crafted URL. For example:
In this case, JWT.io and the extensions will attempt to download the key with
kid = 1 from the special URL
https://username.auth0.com/.well-known/jwks.json. This is a common scheme used by Auth0. In other words, all Auth0 JWTs can now be verified in JWT.io and the JWT Debugger extension by simply pasting the token!
"With automatic key downloads, all Auth0 JWTs can now be verified in JWT.io and the JWT Debugger extension by simply pasting the token!"
Of course, since the JWK and JWS standards declare other common schemes for specifying keys, these are also supported: the
x5u claims. These are used to either embed a key within the token (
x5c) or to declare a URL to get the keys or certificates (
x5u). For example:
In this case, JWT.io and the extensions will attempt to download the key with
kid = 1 from the URL
https://username.auth0.com/.well-known/jwks.json specified in the
Human Readable Timestamps
Several JWT claims are time-based. For instance, the
iat claim specifies the exact time the JWT was issued at, the
exp claim specifies the expiration time for the JWT, the
nbf sets the time when the JWT becomes valid, etc. Unfortunately, these claims are based on the Unix epoch: they specify the number of seconds elapsed since January 1st, 1970. Understanding these values by simply looking at them is hard. For this reason, now JWT.io and the JWT Debugger extensions display a tooltip when the mouse hovers over a supported time claim.
The supported claims are:
Yes! It's finally here. Ever since the first release of the JWT Debugger extension for Chrome we have received requests for a Firefox version. Now it's here and supports all the features of the Chrome extension. Get it here!
Although the new features are the cool part of the release, we have also done a ton of internal work on both JWT.io and the extensions. In particular:
- We have closed over 40 issues and merged over 15 pull requests (some with more libraries!).
- We have synchronized the codebases of JWT.io and the JWT Debugger extensions to always get the latest features out to you, regardless of what you use more.
- We have updated all internal dependencies to the latest versions. This has fixed many bugs here and there and also improved the experience on mobile platforms.
- We have performed a major refactor to improve code quality and latencies during page load. JWT.io is now faster than ever!
- We have added more tests to our test suite. Do check that these pass before submitting new PRs!
- Build scripts are now simpler. Want to contribute? Doing so is as simple as:
- Checkout from Git.
That's it! You will now find JWT.io available on http://localhost:8000 and ready for your changes. The extension is also built but you'll need to load it manually in your browser, see the Chrome or Firefox docs for help with this. The resulting code can always be found in the
dist folder. Send your PRs!
Aside: Delegating JWT Implementation to the Experts
JWTs are an integral part of the OpenID Connect standard, an identity layer that sits on top of the OAuth2 framework. Auth0 is an OpenID Connect certified identity platform. This means that if you pick Auth0 you can be sure it is 100% interoperable with any third party system that also follows the specification.
The OpenID Connect specification requires the use of the JWT format for ID tokens, which contain user profile information (such as the user's name and email) represented in the form of claims. These claims are statements about the user, which can be trusted if the consumer of the token can verify its signature.
While the OAuth2 specification doesn't mandate a format for access tokens, used to grant applications access to APIs on behalf of users, the industry has widely embraced the use of JWTs for these as well.
As a developer, you shouldn't have to worry about directly validating, verifying, or decoding authentication-related JWTs in your services. You can use modern SDKs from Auth0 to handle the correct implementation and usage of JWTs, knowing that they follow the latest industry best practices and are regularly updated to address known security risks.
If you want to try out the Auth0 platform, sign up for a free account and get started! With your free account, you will have access to the following features:
- Universal Login for Web, iOS & Android
- Up to 2 social identity providers (like Twitter and Facebook)
- Unlimited Serverless Rules
To learn more about JWTs, their internal structure, the different types of algorithms that can be used with them, and other common uses for them, check out the JWT Handbook.
Although we have just finished with these changes, there's still more in our pipeline!
- Key-length tips: we will show you tooltips when your shared secrets are not long enough.
- Share button: the extensions already support this, now it's coming to JWT.io!
- Library submission process: we get tons of PRs with new libraries, we want to formalize the process and setup tools so that you can easily review any steps that are required to add your library to JWT.io
We hope you enjoy all the new features and changes at JWT.io and the JWT Debugger extensions. Please report any bugs at the GitHub repository and don't forget to leave us your comments or requests here or in the issue tracker at GitHub. Cheers!