前言:
- 本文仅是个人的一个学习记录
- 掌握Java的相关知识
- 了解通过OpenSSL生成RAS密钥文件
正文:
相关依赖:
<!--JWT 依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
测试类:
package com.localhost;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
/**
* @author 花海
* @version 1.0.0
*/
public class JWTDemoUtils {
// 加载wa.jks文件(生成的私钥文件)
private static final InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("wa.jks");
private static PrivateKey privateKey = null;
private static PublicKey publicKey = null;
/**
* 静态代码块
* 读取私钥文件,生成私钥与公钥
*/
static {
try {
// 读取私钥文件
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(inputStream, "wa2000".toCharArray());
// wajiang 私钥文件的别名, wa2000 为私钥密码
privateKey = (PrivateKey) keyStore.getKey("wajiang", "wa2000".toCharArray());
// 私钥文件中的公钥,可用来自行与通过公钥字符串解析的公钥进行对比
// publicKey = keyStore.getCertificate("wajiang").getPublicKey();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
try {
// 非空判断
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
// 采用私钥key加密,私钥与公钥进行解密
// 采用RS256非对称加密
SignatureAlgorithm signatureAlgorithmRS256 = SignatureAlgorithm.RS256;
long nowMillis = System.currentTimeMillis();
// 有效期为
long expMillis = nowMillis + 60 * 60 * 1000L;// 60 * 60 *1000 一个小时
Date expDate = new Date(expMillis); // jwt有效截至时间
// 唯一的ID
String uuid = "wajiang"; // 建议通过UUID生成唯一id
// 签发时间
Date now = new Date(nowMillis);
// 模拟加密数据
String subject = "{\"id\":\"wa2000\",\"name\":\"wa酱\"}";
String jwtString = Jwts.builder()
.setId(uuid) // 唯一的ID
.setSubject(subject) // 主题 可以是JSON数据
.setIssuer("wajiang") // 签发者
.setIssuedAt(now) // 签发时间
.setExpiration(expDate) // 有效时长
.signWith(signatureAlgorithmRS256, privateKey) // 使用RS256对称加密算法签名, 第二个参数为私钥
.compact();// 加密
// 打印结果eyJh~~iJ9.eyJqd~~~0OTh9.SaVFy~~~Rj0A
System.out.println(jwtString);
// 通过公钥字符串获取公钥进行解密
String publicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlRyhKRS6LqeQW5DyTh4Z\n" +
"~\n" +
"9R7xuTTWapBAkMUWQaW5aZlvVNKTY6bkSzcfkfHuTDfa9wLO/qfVcuhTVWXPpbX7\n" +
"4wIDAQAB\n" +
"-----END PUBLIC KEY-----";
String publicKeyString = publicKeyPEM
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s", "");
// 将Base64编码后的公钥字符串转换为PublicKey对象
// 公钥的编码(即二进制数组)
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
// Java 密钥规范,将公钥与身份信息相关联,可用于将 X.509 证书中的公钥转换为 Java 密钥对象(即 java.security.PublicKey 类型的对象)
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
// 加密模式为:RS256非对称加密(RS256是带有SHA-256的 RSA 签名)
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 获取公钥
publicKey = keyFactory.generatePublic(keySpec);
// 解密JWT获取到的结果对象
Claims claims = Jwts.parser()
.setSigningKey(publicKey) // 私钥解密将参数替换为私钥即可
.parseClaimsJws(jwtString) // 待解密的jwt字符串
.getBody();
// 打印解析的结果:{"id":"wa2000","name":"wa酱"}
System.out.println(claims.getSubject());
}
}