Johnny

博观而约取
厚积而薄发

token中的JWT加密解密算法分析

token中的JWT加密解密算法分析

前言

题目是token中的JWT,这边其实就能理解到,token是一个非常大的概念,翻译就是一个令牌的意思,一般用来表示经过验证之后得到的凭证,长度没有限制。token有很多种,可以是自己定义的,也可以是标准的。JWT属于token这个东西的一种、一个标准,整个JWT分为三段式(Header、Payload、Signature),具备自己的验证方式。

请输入图片描述

JWT

Header(头部)

header部分主要是存储JSON对象,描述了JWT的基本属性,主要有两个字段("alg","typ"),alg属性表示Signature的加密算法,typ属性默认写为JWT。最后将header的JSON对象使用Base64URL进行编码转化,放在JWT的第一段。

Payload(负载)

Payload部分也是JSON对象,存放实际上需要传输的数据。JWT官方规定7个字段。

  • iss:签发人
  • exp:过期时间
  • sub:主题
  • aud:受众
  • nbf:生效时间
  • iat:签发时间
  • jti:编号

此处也可自定义添加字段,最终通过Base64URL转换为字符串。

Signature(签名)

Signature是对前两部分的一个签名,主要用于鉴别是否是原始数据,判断有没有被篡改,此处需要指定密钥(secret),解密时无需密钥。

Base64URL

header和payload的编码格式均为Base64URL,这个算法类似于Base64,只是在Base64的基础上,对部分字符进行了进一步的编码。

总结

  • JWT不加密,Header、Payload只是通过编码生成字符串,Signature只是通过Header里指定的算法对Header、Payload进行加密,主要用于鉴别token有没有被篡改。
  • JWT一旦签发token,中间无法废止token,除非更改服务器JWT逻辑,所以token有效期一般不宜过长。
  • 暂时存在的疑问,HMAC SHA256算法是如何实现加密需要密钥,但核对却不需要。

源码

package com.springboot.shiro.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.util.Date;

/**
 * @author Johnny
 * @Date: 2020/9/18 11:31
 * @Description:
 */
@Slf4j
public class JWTUtil {
    /**
     * 生成token
     * @param userName
     * @param secret
     * @param role
     * @return
     */
    public static  String getToken(String userName ,String secret,String role){
        String token = null;
        token = JWT.create()
                .withClaim("userName",userName)
                .withClaim("role",role)
                .withExpiresAt(new Date(System.currentTimeMillis()+5*60*10000))
                .sign(Algorithm.HMAC256(secret));
        return token;
    }
    /**
     * 解密token,并返回用户名
     * @param token
     * @return
     */
    @ExceptionHandler
    public static String getUserName(String token){
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getClaim("userName").asString();
    }

    /**
     * 解密token,并返回角色信息
     * @param token
     * @return
     */
    public static String getRole(String token) {
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getClaim("role").asString();
    }

    public static void main(String[] args) {
        String token =  JWTUtil.getToken("123","密钥","管理员");
        System.out.println("加密后的token"+token);
        String username = JWTUtil.getUserName("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoi566h55CG5ZGYIiwidXNlck5hbWUiOiLpn6nmupAiLCJleHAiOjE2MTg0MDU4MDJ9.9DDgpXEOn9CET-MWLV-lLfzcQFCq9H9KspZ8lVBF37M");
        System.out.println("解密后的用户名"+username);
    }
}
本原创文章未经允许不得转载 | 当前页面:Johnny-韩源-期待与你分享生活的每一天 » token中的JWT加密解密算法分析

评论