欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Token的对称与非对称加密

程序员文章站 2024-03-16 17:53:28
...

JWT生成Token

Token在日常服务中使用频率非常高,生成Token的方式也非常多,目前使用最广泛的方法是使用JWT生成Token。使用JWT可以选择不同的加密方式保障Token的安全,并且可以自定义Token携带的信息以便于后台验证,生成的Token还能保存在前端,不需要消耗后端服务器资源。

JWT加密方式

  1. 对称加密 ,对称加密即加密解密都使用同一个**,HS256加密方式就是用户定义一个**(sercret),加密时将**与Token中存储用户信息的map生成token。
  2. 非对称加密 ,非对称使用公共/私钥对: 标识提供方采用私钥生成签名, JWT 的使用方获取公钥以验证签名。由于公钥 (与私钥相比) 不需要保护, 因此大多数标识提供方使其易于使用方获取和使用 (通常通过一个元数据URL)。

两种加密方法实现

-引入依赖

   <dependency>
     <groupId>com.nimbusds</groupId>
      <artifactId>nimbus-jose-jwt</artifactId>
      <version>6.0</version>
  </dependency>

对称加密

public class TokenUtils {

/**
 * 密匙
 */

private static final byte[] secret = "geibosssoftsfdjsikolkjikolkijswm".getBytes();


//生成一个token
public static String creatTokenHS256(Map<String,Object> payloadMap) throws JOSEException {

    /**
     * JWSHeader参数:加密算法法则
     *
     * JWSAlgorithm:类里面有所有的加密算法法则,直接调用。
     */
    JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);

    //建立一个载荷Payload
    Payload payload = new Payload(new JSONObject(payloadMap));

    //将头部和载荷结合在一起
    JWSObject jwsObject = new JWSObject(jwsHeader, payload);

    //建立一个密匙

    JWSSigner jwsSigner = new MACSigner(secret);

    //签名
    jwsObject.sign(jwsSigner);

    //生成token
    return jwsObject.serialize();

}

public static Map<String,Object> validHS256(String token) throws ParseException, JOSEException {
// 解析token
    JWSObject jwsObject = JWSObject.parse(token);
    //建立一个解锁密匙
    JWSVerifier jwsVerifier = new MACVerifier(secret);
    return verify(jwsObject, jwsVerifier);
}


//验证token信息
private static Map<String,Object> verify(JWSObject jwsObject,JWSVerifier jwsVerifier) throws JOSEException {
    Map<String, Object> resultMap = new HashMap<>();
    //获取到载荷
    Payload payload=jwsObject.getPayload();
    //判断token
    if (jwsObject.verify(jwsVerifier)) {
        resultMap.put("Result", 0);
        //载荷的数据解析成json对象。
        JSONObject jsonObject = payload.toJSONObject();
        resultMap.put("data", jsonObject);
        //判断token是否过期
        if (jsonObject.containsKey("exp")) {
            Long expTime = Long.valueOf(jsonObject.get("exp").toString());
            Long nowTime = DateUtils.getTime();
            //判断是否过期
            if (nowTime > expTime) {
                //已经过期
                resultMap.clear();
                resultMap.put("Result", 2);
            }
        }
    }else {
        resultMap.put("Result", 1);
    }
    return resultMap;
}

}

非对称加密

public class JwtUtils {

/**
 * 创建加密key
 */
public static RSAKey getKey() throws JOSEException {
    RSAKeyGenerator rsaKeyGenerator = new RSAKeyGenerator(2048);
    RSAKey rsaJwk = rsaKeyGenerator.generate();
    System.out.println("加密key是" + rsaJwk);
    return rsaJwk;
}

/**
 * @param payloadMap token的主题部分
 * @param rsaJwk     rsa加***
 * @return 加密后的token
 * @throws JOSEException
 */
public static String creatToken(Map<String, Object> payloadMap, RSAKey rsaJwk) throws JOSEException {
    //私**匙
    JWSSigner signer = new RSASSASigner(rsaJwk);
    //构建token主体
    JWSObject jwsObject = new JWSObject(
            new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(rsaJwk.getKeyID()).build(),
            new Payload(new JSONObject(payloadMap))
    );
    //进行加密
    jwsObject.sign(signer);
    //生成token
    String token = jwsObject.serialize();
    return token;
}

/**
 * @param token  相关token
 * @param rsaJwk 相关**
 * @return
 * @throws ParseException
 * @throws JOSEException
 */
public static Map<String, Object> validToken(String token, RSAKey rsaJwk) throws ParseException, JOSEException {
    //获取到公钥
    RSAKey rsaKey = rsaJwk.toPublicJWK();
    JWSObject jwsObject = JWSObject.parse(token);
    JWSVerifier jwsVerifier = new RSASSAVerifier(rsaKey);
    //验证数据
    Map<String, Object> tokenMap = new HashMap<>();
    //记录token主体信息
    Payload payload = jwsObject.getPayload();
    //判断token是否合法
    if (jwsObject.verify(jwsVerifier)) {
        tokenMap.put("Result", 0);
        //将token数据转为json对象
        JSONObject jsonObject = payload.toJSONObject();
        //将token数据存入map中
        tokenMap.put("Data", jsonObject);
        //判断token是否过期
        if (jsonObject.containsKey("exp")) {
            //获取token保存的过期时间
            Long expTime = Long.valueOf(jsonObject.get("exp").toString());
            //获取当前时间戳
            Long nowTime = DateUtils.getTime();
            //判断是否过期
            if (nowTime > expTime) {
                //清除token信息,将其标志为过期
                tokenMap.clear();
                tokenMap.put("Result", 2);
            }
        }
    } else {
        //将token标志为不合法
        tokenMap.put("Result", 1);
    }
    return tokenMap;
}

//从token获取相关参数
public static Object get(String token, RSAKey rsaJwk ,String fieldName){
    try {
        Map<String, Object> validMap = JwtUtils.validToken(token,rsaJwk);
        JSONObject jsonObject = (JSONObject) validMap.get("Data");
        if (jsonObject.get(fieldName) == null){
            return "该参数不存在";
        }else{
            return jsonObject.get(fieldName);
        }
    }catch (ParseException e){
        e.printStackTrace();
    }catch (JOSEException e){
        e.printStackTrace();
    }
    return null;
}

}

相关标签: Token