Java Web JWT 认证

Java Web JWT 认证

Jwt

分类

  • jws 签名 payload 不分只是编码不加密
  • jwe 加密

jws

加密(对称加密)

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();
  • 不需要设置algenczip标题 - 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;