Token的对称与非对称加密
程序员文章站
2024-03-16 17:53:28
...
JWT生成Token
Token在日常服务中使用频率非常高,生成Token的方式也非常多,目前使用最广泛的方法是使用JWT生成Token。使用JWT可以选择不同的加密方式保障Token的安全,并且可以自定义Token携带的信息以便于后台验证,生成的Token还能保存在前端,不需要消耗后端服务器资源。
JWT加密方式
- 对称加密 ,对称加密即加密解密都使用同一个**,HS256加密方式就是用户定义一个**(sercret),加密时将**与Token中存储用户信息的map生成token。
- 非对称加密 ,非对称使用公共/私钥对: 标识提供方采用私钥生成签名, 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;
}
}
上一篇: vue项目中使用md5加密
下一篇: 如何在vue项目中使用md5加密