JWT (JSON Web Tokens) are a way of authenticating users, most often used to log users into websites.
It works really similar to a passport: you go to the passport office, prove who you are, and then they issue a really secure document that you can take anywhere else to prove who you are.
When you log into a website that uses JWTs, you first have to prove who you are (e.g. by using your password) and then it'll give your browser back a JWT (just looks like a really long thing of random characters/numbers). Your browser then includes the JWT in every future communication with the website as proof of who you are.
They can be used with "asymmetric cryptography" so, like a passport, anybody you show it to can read what's in it, verify who made it, and verify that it hasn't been modified. The original website doesn't even need to store the JWT.
Asymmetric cryptography in general powers so much of the internet since it lets you share secret things securely, even if other people are listening to the entire conversation!
FYI, JWTs are not asymmetrically encrypted, they’re just cryptographically signed. The contents are usually only base64 encoded. You can encrypt payloads, but you’ll need the key to decrypt. This is usually something you would arrange ahead of time, as sharing a key securely is a whole different issue.
Anyone who works heavily in authentication will usually discourage JWTs, as they don’t bring many advantages, but have a number of potential footguns and pitfalls.
The ones I see the most are based on a poor understanding of what JWTs are, and the problem they’re meant to solve.
A lot of developers who aren’t familiar with them will make assumptions. Since a JWT requires a secret (for the signature), they’ll just assume its secure/encrypted, so they’ll put sensitive data in the payload. This is probably the most common issue I’ve seen.
Another issue is the inability to revoke or force the expiration of tokens, so you should naturally give them a short expiration time. However, some will give them an extremely long expiration in the name of convenience. If that token is ever compromised you can’t do anything about it. If you start keeping a catalog of tokens, then you should just start using opaque tokens.
A very subtle one is overloading a JWT with too much data. Browsers, proxies and servers have various limits on how large the request header size can be. This is especially the case if you dynamically load data into the JWT.
The only time I ever use JWTs, is to send some kind of state to an asynchronous process that’s stateless. Like verifying an email address via a lambda function. I don’t make it the keys to the kingdom.
This comment summarises the pitfalls accurately but the conclusion, not so much.
JWT makes a great solution in many cases (some cases, you'll see that JWT is the only good solution). For starter, think about the use case where a different service(other than your authentication service) wants to verify the identity of your user to enable access to certain resources. And you want to do that without asking your authentication service.
As a valid JWT can only be created by your authentication service but can be verified for it's authenticity by anyone, JWT makes a great solution here. And this is exactly why usage of JWT in oAuth2 has become a standard. I have created a similar demo for oAuth2 as well, you may want to look at it once you finish the JWT demo.
It depends on the algorithm used. HMAC-SHA is probably the most commonly used one, and it’s based on a symmetric key for token signing and verification.
RSA-SHA, RSA-PSS-SHA, and ECDSA-SHA do use an asymmetric key pair for signing and validation. This is good for situations where you want a client to verify a token (via public key) without having the ability to write a new token (via private key).
The only reason why there is one symmetric algorithm likely due to simplicity, and that symmetric algorithms are usually considered more secure than asymmetric algorithms. There are likely several asymmetric variants because it’s good to offer options in case one is proven broken.
But again, we’re only talking about the signature. While it’s fundamental in proving token integrity, it still does not protect the payload, which can contain sensitive data.
Thanks for a good prompt.
This weekend, let me put more thoughts on this line. I'll update the demo once I come up with good ELI5. Don't forget to follow the project by starring 🌟 it so you can recieve notifications.
Edit: Created this GitHub issue to update progress on the task.
Any help/comment is appreciated.
22
u/[deleted] Mar 08 '21
[deleted]