Java JWT加密、解密

介绍

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

1、引入包


      <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));
  }

测试结果

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
Java中使用JWT(JSON Web Token)进行加密解密是一种常见的身份验证和授权机制。JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。 1. 头部(Header):包含了算法和令牌类型等信息,通常使用Base64编码表示。 2. 载荷(Payload):包含了要传输的数据,比如用户ID、角色等信息,同样使用Base64编码表示。 3. 签名(Signature):使用私钥对头部和载荷进行签名,以确保数据的完整性和真实性。 下面是使用Java进行JWT加密解密的步骤: 1. 导入相关依赖:在项目的pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> ``` 2. 创建JWT生成器:使用`Jwts.builder()`创建一个JWT生成器对象。 ```java JwtBuilder builder = Jwts.builder(); ``` 3. 设置头部和载荷信息:使用`setHeader()`和`setClaims()`方法设置头部和载荷信息。 ```java builder.setHeader(headerMap); builder.setClaims(claimsMap); ``` 4. 设置签名:使用`signWith()`方法设置签名算法和私钥。 ```java builder.signWith(SignatureAlgorithm.HS256, secretKey); ``` 5. 生成JWT:使用`compact()`方法生成最终的JWT字符串。 ```java String jwt = builder.compact(); ``` 6. 解密JWT:使用`Jwts.parser()`创建一个JWT解析器对象,并使用`setSigningKey()`方法设置公钥或密钥。 ```java Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody(); ``` 以上是使用Java进行JWT加密解密的基本步骤。需要注意的是,生成JWT时需要使用私钥进行签名,解密JWT时需要使用公钥或密钥进行验证。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

维基框架

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值