Java Web JWT 认证
Jwt
分类
- jws 签名 payload 不分只是编码不加密
- jwe 加密
jws
加密(对称加密)
Header
String jwt = Jwts.builder()
.header() // <----
.keyId("aKeyId")
.x509Url(aUri)
.add("someName", anyValue) //自定义头部参数
.add(mapValues)
// ... etc ...
.and() // go back to the JwtBuilder
.subject("Joe") // resume JwtBuilder calls...
// ... etc ...
.compact();
- 不需要设置
alg、enc或zip标题 - JJWT 将始终根据需要自动设置它们。
payload
content
- 字节数组
byte[] content = "Hello World".getBytes(StandardCharsets.UTF_8);
String jwt = Jwts.builder()
.content(content, "text/plain") // <---
// ... etc ...
.build();
claims
- 标准claims:
issure, subject, audience, expiration, notBefore, issuedAt, id - 自定义
String jws = Jwts.builder()
.claim("hello", "world")
// ... etc ...
- map
Map<String,?> claims = getMyClaimsMap(); //implement me
String jws = Jwts.builder()
.claims(claims)
// ... etc ...
加密秘钥
- 自动生成
SecretKey key = Jwts.SIG.HS256.key().build(); //or HS384.key() or HS512.key()
// 转成base64后再存储
String secretString = Encoders.BASE64.encode(key.getEncoded());
-
手动指定
-
编码的字节数组:
SecretKey key = Keys.hmacShaKeyFor(encodedKeyBytes); -
Base64 编码的字符串:
SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString)); -
Base64URL 编码的字符串:
SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64URL.decode(secretString)); -
原始(非编码)字符串(例如密码字符串):
Password key = Keys.password(secretString.toCharArray());
Keys.hmacShaKeyFor(secretString.toCharArray()) ```
加密方法
- 常见签名算法
io.jsonwebtoken.Jwts.SIG类中
| 标识符 | 签名算法 |
|---|---|
HS256 |
使用 SHA-256 的 HMAC |
HS384 |
使用 SHA-384 的 HMAC |
HS512 |
使用 SHA-512 的 HMAC |
ES256 |
使用 P-256 和 SHA-256 的 ECDSA |
ES384 |
使用 P-384 和 SHA-384 的 ECDSA |
ES512 |
使用 P-521 和 SHA-512 的 ECDSA |
RS256 |
使用 SHA-256 的 RSASSA-PKCS-v1_5 |
RS384 |
使用 SHA-384 的 RSASSA-PKCS-v1_5 |
RS512 |
使用 SHA-512 的 RSASSA-PKCS-v1_5 |
PS256 |
RSASSA-PSS 使用 SHA-256 和 MGF1 与 SHA-256 1 |
PS384 |
RSASSA-PSS 使用 SHA-384 和 MGF1 与 SHA-384 1 |
PS512 |
RSASSA-PSS 使用 SHA-512 和 MGF1 与 SHA-512 1 |
EdDSA |
Edwards-Curve 数字签名算法 (EdDSA) 2 |
-
秘钥的长度有规定
-
HS256是 HMAC-SHA-256,它产生的摘要长度为 256 位(32 字节),因此HS256_要求_您使用长度至少为 32 字节的密钥。 -
HS384是 HMAC-SHA-384,它产生的摘要长度为 384 位(48 字节),因此HS384_要求_您使用长度至少为 48 字节的密钥。 -
HS512是 HMAC-SHA-512,它产生的摘要长度为 512 位(64 字节),因此HS512_要求_您使用长度至少为 64 字节的密钥。
-
-
示例
// 不指定加密方法 jwts会自动指定, 并写到头部.
.signWith(privateKey, Jwts.SIG.RS512) // <---
.compact();
完整实例
SecretKey secretKey1 = Keys.hmacShaKeyFor(secretKey.getBytes());
JwtBuilder builder = Jwts.builder()
.signWith(secretKey1, Jwts.SIG.HS256)
// 设置过期时间
.expiration(exp)
.claims(claims);
return builder.compact();
解密(对称加密)
content
// create a test key for this example:
SecretKey testKey = Jwts.SIG.HS512.key().build();
String message = "Hello World. It's a Beautiful Day!";
byte[] content = message.getBytes(StandardCharsets.UTF_8);
String jws = Jwts.builder().signWith(testKey) // #1
.content(content) // #2
.encodePayload(false) // #3
.compact();
Jws<byte[]> parsed = Jwts.parser().verifyWith(testKey) // 1
.build()
.parseSignedContent(jws, content); // 2
assertArrayEquals(content, parsed.getPayload());
claims
Jwts.parser()
.verifyWith(secretKey) // <----
.build()
.parseSignedClaims(jwsString);
.getPayload();
return payload;