Java JWT加密、解密

维基框架 2024-09-12 15:05:02 阅读 80

介绍

        JSON Web 令牌 (JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且独立的方式,用于作为 JSON 对象在各方之间安全地传输信息。由于此信息已进行数字签名,因此可以对其进行验证和信任。可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对对 JWT 进行签名。

1、引入包

<code>

<dependency>

<groupId>com.auth0</groupId>

<artifactId>java-jwt</artifactId>

<version>3.8.1</version>

</dependency>

<dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt</artifactId>

<version>3.8.1</version>

</dependency>

2、签名算法

/**

* 签名算法

*/

private static final SignatureAlgorithm signatureAlgorithm;

3、静态实例化值

/**

* 静态默认值

*/

static {

signatureAlgorithm = SignatureAlgorithm.HS512;

}

4、加密

/**

* 前三个参数为自己用户token的一些信息比如id,权限,名称等。不要将隐私信息放入(大家都可以获取到)

*

* @param map 参数

* @param base64Security 密钥

* @return 返回结果

*/

public static String createJwt(Map<String, Object> map, String base64Security) {

//添加构成JWT的参数

JwtBuilder builder = builderJwt(map, base64Security);

//生成JWT token

return builder.compact();

}

/**

* 前三个参数为自己用户token的一些信息比如id,权限,名称等。不要将隐私信息放入(大家都可以获取到)

*

* @param map 参数

* @param base64Security 密钥

* @param expiration 过期时间

* @return 返回结果

*/

public static String createJwt(Map<String, Object> map, String base64Security, long expiration) {

//添加构成JWT的参数

JwtBuilder builder = builderJwt(map, base64Security);

builder.setExpiration(new Date(expiration));

//生成JWT

return builder.compact();

}

/**

* 构建 jwt

*

* @param map 值

* @param base64Security 密钥

* @return 返回结果

*/

private static JwtBuilder builderJwt(Map<String, Object> map, String base64Security) {

return Jwts.builder().setHeaderParam("typ", "JWT")

.setClaims(map)

//估计是第三段密钥

.signWith(signatureAlgorithm, base64Security.getBytes());

}

5、解密

/**

* 解密

*

* @param jsonWebToken token

* @param base64Security 密钥

* @return 返回结果

*/

public static Claims parseJwt(String jsonWebToken, String base64Security) {

try {

Claims claims = Jwts.parser()

.setSigningKey(base64Security.getBytes())

.parseClaimsJws(jsonWebToken).getBody();

return claims;

} catch (Exception ex) {

ex.printStackTrace();

return null;

}

}

6、检查token

/**

* 检查token

*

* @param jwtToken token

* @param base64Security base64安全性

* @param userAgent 用户代理

* @return 返回 redis token

* @throws Exception 异常信息

*/

public static String checkToken(String jwtToken, String base64Security, String userAgent) throws GlobalException {

String token;

try {

Claims claims = parseJwt(jwtToken, base64Security);

long effective = IntegerConsts.TWENTY_FOUR * IntegerConsts.SIXTY * IntegerConsts.SIXTY;

Long time = ConvertUtils.convertLong(claims.get(BusinessConsts.TIME));

if (time <= IntegerConsts.ZERO) {

time = ConvertUtils.convertLong(claims.get(BusinessConsts.EXP));

}

// 验证 token 是否过期

LocalDateTime localDateTime = LocalDateUtils.timestampToLocalDateTime(time)

.plusSeconds(effective);

if (LocalDateUtils.greater(localDateTime, LocalDateTime.now())) {

throw new GlobalException("token 过期!");

}

// 验证 token 签名

Object loginName = claims.get(BusinessConsts.USER_NAME);

if (StringUtils.isNullAndSpaceOrEmpty(loginName)) {

loginName = claims.get(BusinessConsts.LOGIN_NAME);

}

StringBuilder builder = new StringBuilder();

builder.append(String.format("loginName=%s&effective=%s&time=%s&userAgent=%s", loginName, effective, time, userAgent));

token = String.valueOf(claims.get(BusinessConsts.HEADER_TOKEN));

String tokenPassword = Md5Utils.getMd5(builder.toString());

if (!tokenPassword.equals(token)) {

throw new GlobalException("token 签名验证失败!");

}

} catch (Exception ex) {

String message = "token 验证失败!";

if (ex instanceof GlobalException) {

message = ex.getMessage();

}

throw new GlobalException(message);

}

// 返回结果

return token;

}

7、测试

public static void main(String[] args) {

// 生成 JWT token

Map<String, Object> map = new HashMap<>(IntegerConsts.FOUR);

map.put(BusinessConsts.LOGIN_NAME, "username");

long time = System.currentTimeMillis() / IntegerConsts.ONE_THOUSAND;

map.put(BusinessConsts.TIME, time);

map.put(BusinessConsts.USER_NAME, "username");

map.put(BusinessConsts.USER_TYPE, "userType");

map.put(BusinessConsts.DISPLAY_NAME, "displayName");

// 暂不需要该参数

String userAgent = StringUtils.Empty;

StringBuilder builder = new StringBuilder();

/**

* 加密 token 参数

*/

long EFFECTIVE = IntegerConsts.TWENTY_FOUR * IntegerConsts.SIXTY * IntegerConsts.SIXTY;

String TOKEN_ENCRYPTION = "loginName=%s&effective=%s&time=%s&userAgent=%s";

builder.append(String.format(TOKEN_ENCRYPTION,

"username", EFFECTIVE, time, userAgent));

String tokenValue = Md5Utils.getMd5(builder.toString());

map.put(BusinessConsts.HEADER_TOKEN, tokenValue);

//密钥

String key = "cdkj-framework-jwt";

String token = JwtUtils.createJwt(map, key, System.currentTimeMillis() + 10000);

try {

JwtUtils.checkToken(token, key, "");

} catch (Exception e) {

e.printStackTrace();

}

System.out.println("JWT加密的结果:" + token);

System.out.println("JWT解密的结果:" + parseJwt(token, key));

}

测试结果



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。