下面展示一些 内联代码片
。
最新版本 jjwt-api
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-jackson -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
HMAC (基于哈希的消息身份验证代码)对 JWT 进行数字签名。
JWT 规范定义了 3 种标准 HMAC 签名算法:
HS256:具有 SHA-256 的 HMAC。这需要 256 位(32 字节)SecretKey或更大。
HS384:具有 SHA-384 的 HMAC。这需要 384 位(48 字节)SecretKey或更大。
HS512:具有 SHA-512 的 HMAC。这需要 512 位(64 字节)SecretKey或更大。
ES256:使用 P-256 和 SHA-256 的 ECDSA。这需要正好 256 位(32 字节)长的 EC 密钥。
ES384:使用 P-384 和 SHA-384 的 ECDSA。这需要正好 384 位(48 字节)长的 EC 密钥。
ES512:使用 P-521 和 SHA-512 的 ECDSA。这需要 EC 密钥的长度恰好为 521 位(65 或 66 字节,具体取决于格式)。
Ed25519:EdDSA使用曲线Ed25519。Ed25519算法密钥必须为 255 位长,并生成 512 位(64 字节)长的签名。
Ed448:EdDSA使用曲线Ed448。Ed448算法密钥必须为 448 位长,并生成 912 位(114 字节)长的签名。
A128GCM:使用 128 位(16 字节)SecretKey或更大的 AES GCM。
A192GCM:使用 192 位(24 字节)SecretKey或更大的 AES GCM。
A256GCM:使用 256 位(32 字节)SecretKey或更大的 AES GCM。
A128CBC-HS256:AES_128_CBC_HMAC_SHA_256使用 256 位(32 字节)SecretKey。
A192CBC-HS384:AES_192_CBC_HMAC_SHA_384使用 384 位(48 字节)SecretKey。
A256CBC-HS512:AES_256_CBC_HMAC_SHA_512使用 512 位(64 字节)SecretKey。
//如果您不想考虑位长度要求,或者只是想让您的生活更轻松,
//JWT 提供了方便的构建器类,可以为任何给定的密钥生成足够安全的密钥
SecretKey secretKey = Jwts.SIG.HS256.key().build();
//自定义秘钥也可以 , 不同的算法需要的秘钥长度不同
//SecretKey key = Keys.hmacShaKeyFor("AWEQWEWE23123156qqqq465wqeqweqweqwewqeqweqweqweq4".getBytes(StandardCharsets.UTF_8)); // 你的密钥
// 独立的Header头
Header Headers = Jwts.header()
.keyId("aKeyId")//秘钥ID, 一般不写
.add("Key","Value")
// ... 可add多个参数 ...
.build();//构建对象
//创建一个Claims对象,可以很多个参数
Claims claims = Jwts.claims().subject("F").add("username", "Feng")
.add("userid", "eqexta939c").build();
Date now = new Date();
Date expiration = new Date(now.getTime() + 700000);
//直接使用Jwts的builder()方法构建完整对象
String jwt = Jwts.builder()
.header() //构建header
.add(Headers)// <----追加上面的独立头信息
.add("key", "v")//自定义更多的头信息
.and()//增加主体信息
.subject("whatever")
//负载(payload)
.claim("img","123.png")//自定义信息
.claim("url","https://xxx.com")//自定义信息
.claims(claims)//上面创建的集合 或者可以自定义一个 java.util.Map map 对象也可以
.issuedAt(now) // 当前时间作为签发时间
.expiration(expiration) // 过期时间
.signWith(secretKey,Jwts.SIG.HS256)
// ... 可以追加更多的参数 ...
.compact();//生成签名
System.out.println(jwt);
生成结果
eyJraWQiOiJhS2V5SWQiLCJLZXkiOiJWYWx1ZSIsImtleSI6InYiLCJhbGciOiJub25lIn0.eyJzdWIiOiJGIiwiaW1nIjoiMTIzLnBuZyIsInVybCI6Imh0dHBzOi8veHh4LmNvbSIsInVzZXJuYW1lIjoiRmVuZyIsInVzZXJpZCI6ImVxZXh0YTkzOWMiLCJpYXQiOjE3MDA3MDcyNDgsImV4cCI6MTcwMDcwNzk0OH0.
//解密签名
Jwt<?, ?> parse = Jwts.parser().verifyWith(secretKey).build().parse(jwt);
System.out.println(parse.getHeader().get("Key"));
System.out.println(parse.getPayload().toString());
解密结果
Value
{sub=F, img=123.png, url=https://xxx.com, username=Feng, userid=eqexta939c, iat=1700709148, exp=1700709848}
在不需要头信息的情况下, 使用parseSignedClaims方法更加方便使用
Jws<Claims> claimsJwt = Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(jwt);
Claims claimsJwtPayload = claimsJwt.getPayload();
System.out.println("--------------------------------------");
System.out.println(claimsJwtPayload.getSubject());
// 从负载中获取数据
String username = claimsJwtPayload.get("username", String.class);
String userid = claimsJwtPayload.get("userid", String.class);
String img = claimsJwtPayload.get("img", String.class);
String url = claimsJwtPayload.get("url", String.class);
String myKey = claimsJwtPayload.get("key", String.class);
// 打印获取的数据
System.out.println("Username: " + username);
System.out.println("User ID: " + userid);
System.out.println("myKey: " + myKey);
System.out.println("img: " + img);
System.out.println("url: " + url);
System.out.println("Subject : " + claimsJwtPayload.getSubject());
System.out.println("Expiration : " + claimsJwtPayload.getExpiration());
System.out.println("IssuedAt : " + claimsJwtPayload.getIssuedAt());
输出结果
F
Username: Feng
User ID: eqexta939c
myKey: null
img: 123.png
url: https://xxx.com
Subject : F
Expiration : Thu Nov 23 11:24:08 CST 2023
IssuedAt : Thu Nov 23 11:12:28 CST 2023
// 创建一个测试的秘钥 HMAC-SHA :
MacAlgorithm alg = Jwts.SIG.HS512; //or HS384 or HS256
SecretKey key = alg.key().build();
String message = "Hello World!";
byte[] content = message.getBytes(StandardCharsets.UTF_8);
//加密,指定Jwts.SIG.HS512算法加密
String jws = Jwts.builder().content(content, "text/plain")
.signWith(key, alg).compact();
//解密
content = Jwts.parser().verifyWith(key).build()
.parseSignedContent(jws).getPayload();
System.out.println(message.equals(new String(content,StandardCharsets.UTF_8)));
// 使用 RSA 加密算法:
SignatureAlgorithm RSAalg = Jwts.SIG.RS512;//or PS512, RS256, etc...
//创建秘钥
KeyPair pair = RSAalg.keyPair().build();
// 使用私钥加密
String RSAjws = Jwts.builder().subject("Alice")
.signWith(pair.getPrivate(), RSAalg) // <-- 私钥
.compact();
// 使用公钥解密
String subject = Jwts.parser()
.verifyWith(pair.getPublic()) // <-- 公钥
.build().parseSignedClaims(RSAjws).getPayload().getSubject();
System.out.println( "Alice".equals(subject));
//使用 ECDSA 算法加密:
SignatureAlgorithm ECDSAAlg = Jwts.SIG.ES512; //or ES256 or ES384
//创建秘钥
KeyPair ECDSAPair = ECDSAAlg.keyPair().build();
// 使用私钥加密
String ECDSAJws = Jwts.builder().subject("Alice")
.signWith(ECDSAPair.getPrivate(), ECDSAAlg) // <-- 私钥
.compact();
// 使用公钥加密
String ECDSASubject = Jwts.parser()
.verifyWith(ECDSAPair.getPublic()) // <-- 公钥
.build().parseSignedClaims(ECDSAJws).getPayload().getSubject();
System.out.println("Alice".equals(ECDSASubject));
//使用 Ed25519 加密算法:
Curve curve = Jwks.CRV.Ed25519; //or Ed448
//创建秘钥
KeyPair Ed25519pair = curve.keyPair().build();
// 私钥加密
String Ed25519jws = Jwts.builder().subject("Alice")
.signWith(Ed25519pair.getPrivate(), Jwts.SIG.EdDSA) // <-- 私钥
.compact();
// 公钥解密
String Ed25519subject = Jwts.parser()
.verifyWith(Ed25519pair.getPublic()) // <-- 公钥
.build().parseSignedClaims(Ed25519jws).getPayload().getSubject();
System.out.println("Alice".equals(Ed25519subject));
//可以生成秘钥或者自定义秘钥,长度参考
SecretKey key = Keys.hmacShaKeyFor("AWEQWEWE23123156qqqq465wqeqweqweqwewqeqweqweqweq4".getBytes(StandardCharsets.UTF_8)); // 你的密钥
String AESSub="xiaoming";
Claims claims1 = Jwts.claims().subject(AESSub)
.add("username", "ming")
.add("userid", "exisxxxxc")
.add("avatar", "https://res.wx.qq.com/a/wx_fed/weixin_portal/res/static/img/1L3ryyg.png").build();
String token = Jwts.builder().claims(claims1)
.issuedAt(now) // 当前时间作为签发时间
.expiration(expiration) // 过期时间
.signWith(key, Jwts.SIG.HS256)//秘钥
.compact();
Jws<Claims> claimsJws = Jwts.parser()
.verifyWith(key) // <----秘钥
.build()
.parseSignedClaims(token);
System.out.println(AESSub.equals(claimsJws.getPayload().getSubject()));
System.out.println(claimsJws.getPayload());