DEV Community


Posted on • Updated on

Why PASETO is better than JWT for token-based authentication?


Nowadays, token-based authentication has become more and more popular in the development of web and mobile applications.

There are many different types of tokens, but among them, JSON web token (or JWT) is one of the most widely used.

However, in the past few years, we’ve also discovered several security issues regarding JSON web token, mainly because of its poorly designed standard.

So recently people have started migrating to other types of tokens such as PASETO, which promises to bring better security to the application.

In this lecture, we will learn everything about the security issues of JWT and how PASETO is designed to solve all of those problems.


Token-based authentication

First, let’s talk a bit about token-based authentication.

Basically, in this authentication mechanism, the client will make the first request to log in user, where it provides the username and password to the server.

Alt Text

The server will check if the username and password are correct or not. If they are, the server will create and sign a token with its secret or private key, then sends back a 200 OK response to the client together with the signed access token.

The reason it’s called access token is that later the client will use this token to get access to other resources on the server.

For example, let’s say the client wants to get the list of bank accounts that belong to the logged-in user. Then it will make a GET /accounts request to the server, where it embeds the user’s access token in the header of the request.

Alt Text

Upon receiving this request, the server will verify if the provided token is valid or not. If it is valid, the request will be authorized, and a 200 OK response will be sent back to the client with the list of user’s bank accounts.

Note that an access token normally has a lifetime duration before it gets expired. And during this time, the client can use the same token to send multiple requests to the server.

So that’s how the token-based authentication works.

JSON Web Token

Now let’s talk about JSON Web Token! Here’s an example of a JSON Web Token:

Alt Text

It is a base64 encoded string, composed of 3 main parts, separated by a dot.

The first part (with the color red) is the header of the token. When we decode this part, we will get a JSON object that contains the token type JWT, and the algorithm used to sign the token: HS256 in this case.

The second part (in purple) of the token is the payload data. This part is where we store information about the logged-in user, such as username, and also the timestamp at which this token will be expired.

Alt Text

You can customize this JSON payload to store any other information you want. In this case, we also have an ID field to uniquely identify the token. It will be useful in case we want to revoke access of the token in case it is leaked.

Keep in mind that all data stored in the JWT is only base64-encoded, not encrypted. So you don’t need the secret/private key of the server in order to decode its content.

It also means that we can easily encode the header and payload data without the key. So how can the server verify the authenticity of the access token?

Well, that’s the purpose of the third part of the token: the digital signature (in blue color). If you don’t know how the digital signature algorithm works, then I recommend you to read my post about SSL/TLS before continuing.

Alt Text

The idea is simple, only the server has the secret/private key to sign the token. So if a hacker attempts to create a fake token without the correct key, it will be easily detected by the server in the verification process.

The JWT standards provide many different types of digital signature algorithms, but they can be classified into 2 main categories.

Symmetric-key algorithm

The first one is symmetric-key algorithm, where the same secret key is used to both sign and verify the tokens.

Alt Text

And since there’s only 1 key, it should be kept secret. So this algorithm is suitable for local use only, or in other words, for internal services, where the secret key can be shared.

Some specific algorithms which belong to this symmetric-key category are: HS256, HS384, and HS512.

Here HS256 is the combination of HMAC and SHA-256. HMAC stands for Hash-based Message Authentication Code, and SHA is the Secure Hashing Algorithm. While 256/384/512 is the number of output bits.

Alt Text

Symmetric-key algorithm is very efficient and suitable for most applications.

However, we cannot use it in case there’s an external third-party service that wants to verify the token, because it would mean we must give them our secret key.

In that case, we must use the second category: asymmetric-key algorithm.

Asymmetric-key algorithm

In this type of algorithm, there’s a pair of keys instead of just 1 single secret key.

Alt Text

The private key is used to sign the token, while the public key is used only to verify it.

Therefore, we can easily share our public key with any external third-party services without worrying about leaking our private key.

Within this asymmetric-key category, there are several groups of algorithms, such as RS group, PS group, or ES group.

Alt Text

Here, RS256 is basically RSA algorithm with PKCSv1.5 and SHA256.

PS256 is also RSA algorithm but with Probabilistic Signature Scheme and SHA256. It was designed to be more secured than PKCSv1.5

And the last one ES256 is simply Elliptic Curve Digital Signature Algorithm with SHA256.

Problems of JWT

OK, so far it sounds like JWT is a good standard, and it gives us a lot of flexibility to choose whatever signing algorithms we want. So what exactly are its problems?

Weak algorithms

Well, the first problem is weak signing algorithms. JWT gives developers too many algorithms to choose from, including the algorithms that are already known to be vulnerable, such as:

  • RSA with PKCSv1.5 is susceptible to a padding oracle attack.
  • Or ECDSA can face an invalid-curve attack.

Alt Text

For developers without deep experience in security, it would be hard for them to know which algorithm is the best to use.

So the fact that JWT gives developers too much flexibility to choose the algorithm is like giving them a gun to shoot themselves in the foot.

Trivial Forgery

But it’s not the worst. JSON web token makes token forgery so trivial, that if you are not careful in your implementation or if you choose a poorly implemented library for your project, your system will easily become a vulnerable target.

One bad thing about JWT is that it includes the signing algorithm in the token header.

Because of this, we have seen in the past, an attacker can just set the alg header to none to bypass the signature verification process.

Of course, this issue has been identified and fixed in many libraries, but it’s something you should carefully check when choosing the community-developed library for your project.

Alt Text

Another more dangerous potential attack is to purposely set the algorithm header to a symmetric-key one, such as HS256 while knowing that the server actually uses an asymmetric-key algorithm, such as RSA to sign and verify the token.

Let me explain how!

Basically, the server’s RSA public key is clearly known to the public because it’s a public key.

So the hacker can just create a fake token of the admin user, where he purposely set the algorithm header to HS256, which is a symmetric-key algorithm.

Then, he just signs this token with the server’s public key and uses it to access resources on the server.

Alt Text

Now, keep in mind that, the server normally uses an RSA algorithm, such as RS256 to sign & verify the token, so it will use the RSA public key as the key to verify the token signature.

However, since the token’s algorithm header is saying HS256, the server will verify the signature with this symmetric algorithm HS256 instead of RSA.

And because the same key is used by the hacker to sign the token payload, this signature verification process will be successful, and the request of the hacker will be authorized.

This kind of attack is very simple, but still so powerful and dangerous, and it has actually happened in the past because the developers didn’t check the algorithm header before verify the token signature.

So, in order to prevent this attack, it’s crucial that in your server code, you must check the token’s algorithm header to make sure that it matches with the one your server uses to sign and verify tokens.

Alt Text

OK, so now you know why JSON web token is not a very well-designed standard. It opens the door to many potential threats.

Therefore, many people are trying to stay away from it, and migrate to something more robust.

PASETO - Platform Agnostic Security Token

PASETO, or Platform Agnostic Security Token is one of the most successful designs that is being widely accepted by the community as the best-secured alternative to JWT.

Strong algorithms

It solves all issues of JSON web token by first, provide strong signing algorithms out of the box.

Developers don’t have to choose the algorithm anymore. Instead, they only need to select the version of PASETO they want to use.

Alt Text

Each PASETO version has already been implemented with 1 strong cipher suite. And at any time, there will be only at most 2 latest versions of PASETO are active.

Right now, 2 active PASETO versions are version 1 and version 2.

PASETO version 1

Version 1 is older, and should only be used for legacy systems that cannot use modern cryptography.

Similar to JWT, PASETO also has 2 algorithm categories for 2 main use cases.

For local or internal services, we use a symmetric-key algorithm.

Alt Text

But unlike JWT, which only does base64-encode the payload, and sign the token, PASETO actually encrypts and authenticates all data in the token with a secret key, using a strong Authenticated Encryption with Associated Data (or AEAD) algorithm. If you don’t know what AEAD is, you can watch my video about SSL/TLS.

The AEAD algorithm used in PASETO version 1 is AES256 CTR with HMAC SHA384.

For public cases, where there are external services that need to verify the token, we have to use an asymmetric-key algorithm.

In that case, PASETO uses the same approach as JWT, which means, it doesn’t encrypt the token data, but only base64-encode it, and uses the private key to sign the content with a digital signature.

Alt Text

The chosen asymmetric-key algorithm in PASETO version 1 is RSA PSS with SHA384.

PASETO version 2

In the latest version of PASETO (version 2), 2 more secured and modern algorithms are being used.

For local symmetric-key scenario, it uses XChacha20 with Poly1305 algorithm.

Alt Text

And for a public asymmetric-key scenario, Edward-curve digital signature algorithm with curve 25519 is used.

This choice reminds me of how TLS 1.3 was designed to improve the security of its older version TLS 1.2, and also simplify & reduce the number of TLS cipher suites at the same time.

Alt Text

Non-trivial forgery

Now with the design of PASETO, token forgery is no longer trivial.

Because the algorithm header doesn’t exist anymore, so the attacker cannot set it to none, or force the server to use the algorithm it chose in this header.

Alt Text

Everything in the token is also authenticated with AEAD, so it’s not possible to tamper with it.

Moreover, if you use a local symmetric-key algorithm, the payload is now encrypted, not just encoded, so it’s impossible for hackers to read or change the data stored in the token without knowing the server’s secret key.

Sounds amazing, right?

In the next lecture, I’m gonna show you how to implement both JWT and PASETO using Golang.

You will see PASETO not only makes it safer but also easier and so much simpler to implement, compared to JWT.

For now, let’s take a look at the structure of a PASETO token.

Alt Text

This is a PASETO version 2 token for local usage purposes. There are 4 main parts of the token, separated by a dot.

The first part is PASETO version (with red color), which is version 2.

The second part is the purpose of the token, is it used for local or public scenarios? In this case, it is local, which means using a symmetric-key authenticated encryption algorithm.

The third part (with green color) is the main content or the payload data of the token. Note that it is encrypted, so if we decrypt it using the secret key, we will get 3 smaller parts:

Alt Text

  • First, the payload body. In this case, we just store a simple message and the expiration time of the token.
  • Second, the nonce value that is used in both encryption and message authentication process.
  • And finally the message authentication tag to authenticate the encrypted message and its associated unencrypted data.

Alt Text

In this case, the unencrypted data is the version, the purpose, and the footer of the token (with purple color).

You can store any public information in the footer because it won’t be encrypted like the payload body, but only base64 encoded. So anyone who has the token can decode it to read the footer data.

Alt Text

In this case, it is Paragon Initiative Enterprises, the one who invented PASETO.

Note that the footer is optional, so you can have a PASETO token without a footer. For example, this is another PASETO token for the public usage scenario:

Alt Text

It only has 3 parts, with no footer. The first part is PASETO version, which is version 2.

The second part is its purpose: public in this case, which means an asymmetric-key digital signature algorithm is used to sign the token, and its payload data will not be encrypted, but only base64 encoded.

As you can see here, the green part of the payload is actually the encoded body, which we can easily decode to get this JSON object.

Alt Text

While the blue part of the payload is the signature of the token, created by the digital signature algorithm using the private key.

The server will use its paired public key to verify the authenticity of this signature.

Alt Text

And that’s it for today’s lecture about token-based authentication.

We have learned about the design flaws of JSON Web Token that causes many security issues in the past, and how PASETO was invented to fix all of those problems, and thus, make our developers’ life much easier.

I hope you like this article, and see you in the next one, where we will write codes to create and verify JWT and PASETO tokens in Golang.

If you like the article, please subscribe to our Youtube channel and follow us on Twitter or Facebook for more tutorials in the future.

If you want to join me on my current amazing team at Voodoo, check out our job openings here. Remote or onsite in Paris/Amsterdam/London/Berlin/Barcelona with visa sponsorship.

Top comments (6)

jacobbishopxy profile image
Jacob Xie

I've learned a lot from this post. Thank you!

theowenyoung profile image
Owen Young

Thanks for your explain. I've learned a lot!

musclemancoder profile image
Vishal Chowdhary


adityapadhikbl profile image
Aditya Padhi

Very nicely explained.

philip21 profile image
Philip Obiora

ive learnt alot thanks

zhpshanda profile image

will 22 to 58 lectures be released?