Why PASETO is better than JWT for token-based authentication?
Tags: security, webdev, beginners
Published: 2021-02-21 14:49:00

# JWT vs PASETO

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.

{% youtube nBGx-q52KAY %}

Here's:

- Link to the [full series playlist on Youtube](https://bit.ly/backendmaster)
- And its [Github repository](https://github.com/techschool/simplebank)


## 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flrd0g79ghtacxuhfaky.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qoathmrviuuks75jtxlj.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ha0y5ho01caqeot7d3nl.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0xcqap763gzcujy2ykat.png)

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](https://dev.to/techschoolguru/a-complete-overview-of-ssl-tls-and-its-cryptographic-system-36pd) before continuing.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zs4wxjxb4aacxtzi9ps6.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y5z448ujclrlrr3joic8.png)

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](https://en.wikipedia.org/wiki/HMAC), and `SHA` is the [Secure Hashing Algorithm](https://en.wikipedia.org/wiki/Secure_Hash_Algorithms). While `256/384/512` is the number of output bits.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/amw2u8r2fe0u778zp00u.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5o4de7x2tdyxuw0drk4u.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k8prmm2bqjaqmusm9xn.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2kgptepmn8zs152cpal.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhfw2cggm6t65b0aq0us.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysgena5bdkmjr3gjqb5m.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usezp4fatfx2fhnkpfrz.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kpgc5in54taj9redhmac.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/epv1xn1vzext7by4z7tp.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tp3muy1xqvzqm8acepdh.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/culilg3cup1lbwysnfiq.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2mu9y1wql9fqxrfnr35q.png)

### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1tq85pqgtfavdoqp9x4.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vn2qc6bhh6mv9afqve5a.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/px5klctnoej5xetwk8ca.png)

- 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ods1mwe7pn2xdmaa5u3h.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8p9xsz755c1q9r3msbcw.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uyf742m4i9e8jw63kzgo.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/18vplnsor3kjeb8xv56j.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vfop1unggl8vzina7vq9.png)

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](http://bit.ly/techschoolguru) and follow us on [Twitter](https://twitter.com/techschoolguru) or [Facebook](https://www.facebook.com/techschool.guru) 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](https://bit.ly/voodoojobs). Remote or onsite in Paris/Amsterdam/London/Berlin/Barcelona with visa sponsorship.