1 introduction

JSON Web Token (JWT) is a very lightweight specification. This specification allows us to use JWT to deliver secure and reliable information between the user and the server.

2 of JWT

A JWT is essentially a string made up of three parts, a header, a payload, and a signature.

2.1 the head the Header

The header describes the most basic information about the JWT, such as its type and the algorithm used to sign it. This can also be represented as a JSON object.

{"typ":"JWT"."alg":"HS256"}
Copy the code

Indicates in the header that the signature algorithm is HS256 algorithm. We do BASE64 encoding and the encoded string looks like this:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
Copy the code

Base64 is a representation of binary data based on 64 printable characters. Since 2 to the sixth power is equal to 64, every six bits is a cell corresponding to some printable character. Three bytes have 24 bits, corresponding to four Base64 units, that is, three bytes need to be represented by four printable characters. JDK provides a very convenient BASE64Encoder and BASE64Decoder, with them can be very convenient to complete base64-based coding and decoding.

2.2 load content

The payload is where the useful information is stored. The name seems to refer specifically to the cargo carried on the plane, and this valid information consists of three parts:

2.2.1 Declaration of registration in the Standard (recommended but not mandatory)

  • Iss: JWT issuer
  • Sub: The user JWT is targeting
  • Aud: The side receiving the JWT
  • Exp: indicates the expiration time of the JWT. The expiration time must be greater than the issue time
  • NBF: defines the time before the JWT is unavailable.
  • Iat: issue time of JWT
  • Jti: Unique IDENTIFIER of the JWT. It is used as a one-time token to avoid replay attacks.

2.2.2 Public declarations

Public declarations can add any information, usually about the user or other information necessary for the business. However, it is not recommended to add sensitive information because this part can be decrypted on the client side.

2.2.3 Private declaration

Private declarations are defined by both providers and consumers. Sensitive information is generally not recommended because Base64 is symmetrically decrypted, meaning that part of the information can be classified as plaintext information. This refers to a custom claim.

Define a payload.

{"sub":"66777"."name":"Jesse"."admin":true}
Copy the code

It is then base64 encoded to get the second part of Jwt:

eyJzdWIiOiI2Njc3NyIsIm5hbWUiOiJKZXNzZSIsImFkbWluIjp0cnVlfQ==
Copy the code

2.3 visa signature

The third part of the JWT is a visa information, which consists of three parts:

  • Header (base64) — The header
  • Payload (base64) — The payload
  • Secret – salt

This part is used by the base64-encrypted header and the Base64-encrypted payload. A string of concatenated strings, then salted secret with the encryption method declared in the header, which forms the third part of the JWT.

Note: the following HMACSHA256() method is I from the Internet to find a encryption method, correctness unknown, you see the general meaning of the line, anyway JJWT will automatically implement salt operation.

public static String HMACSHA256(String data, String key) throws Exception {
	Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
	SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
	sha256_HMAC.init(secret_key);
	byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
	StringBuilder sb = new StringBuilder();
	for (byte item : array) {
		sb.append(Integer.toHexString((item & 0xFF) | 0x100), 1.3);
        }
	return sb.toString().toUpperCase();
}

public static void main(String[] args) throws Exception {
	String encodedString = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2Njc3NyIsIm5hbWUiOiJKZXNzZSIsImFkbWluIjp0cnVlfQ==";
	String secret = HMACSHA256(encodedString, "secret");
	System.out.println(secret);
}
Copy the code

Print the visa using the above method:

07EC07E605FF08FA170C8E8FFE214447853EE8D62594CF4C107AD9D4C5FD0713
Copy the code

Concatenate these three parts into a complete string that forms the final JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2Njc3NyIsIm5hbWUiOiJKZXNzZSIsImFkbWluIjp0cnVlfQ==.07EC07E605FF08FA170C8E 8FFE214447853EE8D62594CF4C107AD9D4C5FD0713Copy the code

Note: Secret is stored on the server side, JWT generation is also on the server side, secret is used for JWT signing and JWT authentication, so it is your server side private key and should not be disclosed in any scenario. Once the client is aware of this Secret, it means that the client can issue the JWT itself.