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);
}
}
当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »