Reproduced from the public account “Gopher Searching”

preface

Recently, I am developing a unified authentication service involving THE OIDC protocol, in which the ID_token issued by the authorization code mode uses the JSON Web Token (JWT).

Since the default signature algorithm of the library used this time is different from that of the past, I specially read THE RFC document of JWT (RFC 75191) and gained a deeper understanding of the core content of JWT after reading it.

You can also find out what JWT tokens mean and how to use them on Authing’s website, as well as how to verify tokens in Authing’s system. What is a JWT Token?

01

The one we use most often is JWT

Every time you mention stateless JWT, you will see another session-based user authentication scheme introduced. This is no exception. The Session authentication process usually looks like this:

This scheme has some disadvantages:

  • Session data needs to be accessed from memory or a database
  • Poor scalability. For distributed applications, session data sharing is required

JWT solves these problems:

JWT’s user authentication process has the advantage of putting user data and other information that needs to be used into JWT, which is automatically carried with each request. As long as the key is not leaked, JWT cannot forge it.

A simple JWT example is as follows:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyMDIxLTEwLTI0IDAwOjAwOjAwIiwibmFtZSI6InRvZ2V0dG95b3UifQ.XdF46NflSUjnt-ad Ac6rNZEXI1OD6nxtwGuhz9qkxUACopy the code

Copy and paste the above JWT into jwt.io2.

You can see that JWT is color-coded, separated by two decimal pointsIn the third part of:

  • Header: A JSON object describing the metadata of the JWT. The alG attribute represents the algorithm of the signature, which is HMAC SHA256 (HS256) by default. The TYp attribute represents the type of the token, written as JWT.
  • Payload: A JSON object that stores data to be transmitted. User-defined fields are supported.
  • Signature: This part is the essence of JWT tamper proof. Its value is generated using the Signature of the specified algorithm after the first two parts of base64UrlEncode. Taking default HS256 as an example, if a secret is specified, it will be generated according to the following formula:
HMACSHA256(
 base64UrlEncode(header) + "." + base64UrlEncode(payload),
 secret,
)
Copy the code

At this point, most people’s knowledge of JWT should stop there, and daily use is sufficient, but if you want to know more about JWT, you need to know JOSE.

02

JOSE specification

What is JOSE, and how does it relate to JWT?

JOSE stands for JSON Object Signing and Encryption (RFC 71653, RFC 75204). It defines a set of standards for how to use JSON during network transmission. The JWT we’ve been talking about is actually one of JOSE’s systems.

JWT can be divided into two different implementations JWS and JWE.Most of what we use on a daily basis, called JWT, actually belongs to JWS. Why say so, see below.

03

JWA and JWS and JWK

JWA stands for JSON Web Algorithms (RFC 75185), and as its name implies, JWA defines all the Algorithms involved in JOSE’s architecture, including Base64-URL and SHA, HMAC, RSA and Elliptic Curve

This article won’t go into the principles of the algorithm, just to give you an idea of what JWA does. The first part of the Header in the JWT example above has an ALG attribute with a value of HS256, which is the HMAC+SHA256 algorithm.

JWS stands for JSON Web Signature (RFC 75156). The core of JWS is the Signature, ensuring that data is not tampered with, and the process of checking the Signature is called validation. JWT: Signature JWT: Signature JWT: Signature JWT: Signature

Usually in the client – server mode, JWS using JWA provide HS256 algorithm combined with a key, this way strictly depend on the key, but in a distributed scenario, you may need to validate multiple services all JWT, if you want to save the key in each service, the security will be discounted, you know, once the key leak, Anyone can forge JWT at will.

The solution is to use asymmetric encryption algorithm RSA, RSA has two keys, a public key and a private key, you can use the private key to issue (signature distribution) JWT, use the public key to verify JWT, the public key is available to everyone. In this way, only the authentication service holds the private key for issuance, and the other services can only authenticate.

Here is a JWT generated using RS256 (RSA+SHA256) algorithm:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjF6aXlIVG15M184MDRDOU1jUENHVERmYWJCNThBNENlZG9Wa3VweXdVeU0ifQ.eyJqdGkiOiIzW UJ5eWZ2TDB4b01QNXdwTXVsZ0wiLCJzdWIiOiI2MDE5NDI5NjgwMWRjN2JjMmExYjI3MzUiLCJpYXQiOjE2MTI0NDQ4NzEsImV4cCI6MTYxMzY1NDQ3MSwic 2NvcGUiOiJvcGVuaWQgZW1haWwgbWVzc2FnZSIsImlzcyI6Imh0dHBzOi8vc3RlYW0tdGFsay5hdXRoaW5nLmNuL29pZGMiLCJhdWQiOiI2MDE5M2M2MTBmO TExN2U3Y2IwNDkxNTkifQ.cYyZ6buwAjp7DzrYQEhvz5rvUBhkv_s8xzuv2JHgzYx0jbqqsWrA_-gufLTFGmNkZkZwPnF6ktjvPHFT-1iJfWGRruOOMV9QKP hk0S5L2eedtbKJU6XIEkl3F9KbOFwYM53v3E7_VC8RBj5IKqEY0qd4mW36C9VbS695wZlvMYnmXhIopYsd5c83i39fLBF8vEBZE1Rq6tqTQTbHAasR2eUz1L nOqxNp2NNkV2dzlcNIksSDbEGjTNkWceeTWBRtFMi_o9EWaHExdm5574jQ-ei5zE4L7x-zfp9iAe8neuAgTsqXOa6RJswhyn53cW4DwWg_g26lHJZXQvv_RH ZRlQCopy the code

Copy it to jwt. IO and have a look

Notice where I checked in the green box, there’s a bit of JSON in there, so let’s delete it and look at the input box.

JWK = JWK = JWK = JWK = JWK = JWK = JWK = JWK = JWK = JWK

Of course, JWK stands for JSON Web Key (RFC 75177), which is just JSON, and JWK represents a Key in JSON (JSON fields vary by Key type). For example, the JWK we just deleted:

{ "e": "AQAB", "kty": "RSA", "n": "wVKQLBUqOBiay2dkn9TlbfuaF40_edIKUmdLq6OlvzEMrP4IDzdOk50TMO0nfjJ6v5830_5x0vRg5bzZQeKpHniR0sw7qyoSI6n2eSkSnFt7P-N8gv2KWnw zVs_h9FDdeLOeVOU8k_qzkph3_tmBV7ZZG-4_DEvgvat6ifEC-WzzYqofsIrTiTT7ZFxTqid1q6zrrsmyU2DQH3WdgFiOJVVlN2D0BuZu5X7pGZup_RcWzt_ 9T6tQsGeU1juSuuUk_9_FVDXNNCTObfKCTKXqjW95ZgAI_xVrMeQC5nXlMh6VEaXfO83oy1j36wUoVUrUnkANhp-dnjTdvJgwN82dGQ" }Copy the code

The KTY field is required and represents the key type. It supports EC elliptic curve keys, RSA keys, and OCT symmetric keys.

JWK and the public key format Pem are interchangeable:

We now know that a public key or a JWK is required to verify the JWT, so you might wonder how jwt. IO knows the JWK, and why it automatically fills in the JWK as soon as it is posted.

Jwks. json (iss/.well-known/jwks.json), where the iss is the iss of the Payload.

When you paste JWT in jwt. IO, jwt. IO parses the Header, determines the JWA algorithm, and then parses the Payload. This is the RS256 algorithm.well-known/jwks.jsonThe JWK is obtained to complete the JWS validation.

04

Another implementation of JWT: JWE

We have said, after Signature Signature of JWT JWS means, and the Signature JWS is only for the first two part, guarantee cannot be tampered with, but its content (load) information is exposed (just made base64UrlEncode processing). Therefore, JWS Payload is not suitable for transmitting sensitive data. JWE, another implementation of JWT, addresses this problem.

JWE is called JSON Web Encryption (RFC 75168). The Payload of JWS is the plaintext of The Base64Url, and the data of JWE is encrypted to make JWT more secure.

JWE provides two schemes: shared key scheme and public/private key scheme.

The shared key scheme works by letting all parties know a key and everyone can sign and verify it, which is consistent with JWS.

The public/private key scheme works differently. In JWS, the private key signs the tokens and the parties holding the public key can only verify the tokens. But in JWE, the party holding the private key is the only one that can decrypt the token, and the public key holder can introduce or exchange new data and then re-encrypt it, so JWS and JWE are complementary when using a public/private key scheme.

An easier way to understand this is to think in terms of producers and consumers.

The producer signs or encrypts the data and the consumer can verify or decrypt it. For JWS, the private key signs the JWT, the public key is used for authentication, that is, the producer holds the private key, the consumer holds the public key, and data flows only from the private key holder to the public key holder.

In contrast, with JWE, the public key is used to encrypt data and the private key is used to decrypt it, in which case the data flows only from the public key holder to the private key holder. As shown below (from JWT Handbook9) :

JWE consists of five parts (separated by four decimal points), compared to three parts of JWS. An example of JWE is as follows:

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0. UGhIOguC7IuEvf*NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm1NJn8LE9XShH59* i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ\_\_deLKxGHZ7PcHALUzoOegEI-8E66jX2E4zyJKxYxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIFNPccxR U7qve1WYPxqbb2Yw8kZqa2rMWI5ng8Otv zlV7elprCbuPhcCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTPcFPgwCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A. AxY8DCtDaGlsbGljb3RoZQ. KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY. 9hH0vgRfYgPnAHOd8stkvwCopy the code
  • Protected Header: A JWS-like Header that identifies the encryption algorithm and type.
  • Encrypted Key: The Key used to encrypt ciphertext and other Encrypted data.
  • Initialization Vector: Some encryption algorithms require additional (usually random) data.
  • Encrypted Data (Ciphertext) : Encrypted Data.
  • Authentication Tag: Additional data generated by the algorithm to verify that the ciphertext content is not tampered with.

The generation of these five parts, or JWE encryption, can be divided into seven steps:

  • Generates a random number of a certain size according to the declaration of Header ALg
  • Determine Content Encryption Key (CEK) based on Key management mode
  • Determine JWE Encrypted Key according to Key management mode
  • Calculate the size of the Initialization Vector (IV) required for the selected algorithm. If you don’t, you can skip it
  • If the Header declares zip, the plaintext is compressed
  • Use CEK, IV, and Additional Authenticated Data (AAD) to encrypt content using algorithms declared by Header ENC, resulting in Ciphertext and Authentication Tag
  • Finally, the Token is constructed according to the following algorithm:
base64(header) + '.' +
base64(encryptedKey) + '.' + // Steps 2 and 3
base64(initializationVector) + '.' + // Step 4
base64(ciphertext) + '.' + // Step 6
base64(authenticationTag) // Step 6
Copy the code

JWE is more secure and reliable than JWS, but it is not lightweight and a bit complex.

05

Safety considerations

conclusion

Today, I have told you some of the hidden secrets of JWT and summarized the knowledge points involved:

  • JOSE: A set of standards that govern the use of JSON during network transport
  • JWT: REPRESENTATION encoded in JSON and passed securely by JWS or JWE
  • JWS: Sign and verify tokens
  • JWE: Encrypt and decrypt tokens
  • JWA: Define all the algorithms involved in JOSE architecture
  • JWK: Use JSON to represent the key

Finally, the system diagram of JOSE is attached again, and relevant RFC has been noted on the diagram:

I hope you can learn more about JWT in today’s sharing!


  1. RFC 7519↩
  2. jwt.io↩
  3. RFC 7165↩
  4. RFC 7520↩
  5. RFC 7518↩
  6. RFC 7515↩
  7. RFC 7517↩
  8. RFC 7516↩
  9. JWT Handbook↩