如何实现 NimbusJwtDecoder 和 NimbusJwtEncoder 的共享秘密版本

Pla*_*aul 1 java jwt nimbus-jose-jwt

org.springframework.security.oauth2.jwt我\xe2\x80\x99m 尝试使用具有共享密钥的包中的编码器/解码器来实现解决方案。\n但是当我尝试使用JwtEncodingException。\n我以另一种形式提出了这个问题,但在这里我提供了一个简单的准备执行示例来验证问题。

\n
import com.nimbusds.jose.JOSEException;\nimport com.nimbusds.jose.jwk.source.ImmutableSecret;\nimport com.nimbusds.jose.jwk.source.JWKSource;\nimport com.nimbusds.jose.proc.SecurityContext;\nimport org.springframework.security.oauth2.jwt.*;\nimport javax.crypto.SecretKey;\nimport javax.crypto.spec.SecretKeySpec;\n\npublic class EncoderDecoderTest {\n  public static String secret = "j8IoV1jF67";\n\n  public JwtEncoder jwtEncoder() throws JOSEException {\n    SecretKey originalKey = new SecretKeySpec(secret.getBytes(), "AES");\n    JWKSource<SecurityContext> immutableSecret = new ImmutableSecret<SecurityContext>(originalKey);\n    return new NimbusJwtEncoder(immutableSecret);\n  }\n  public JwtDecoder jwtDecoder() {\n    SecretKey originalKey = new SecretKeySpec(secret.getBytes(), "AES");\n    NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withSecretKey(originalKey).build();\n    return jwtDecoder;\n  }\n\n  public void tester() throws JOSEException {\n    JwtClaimsSet claims = JwtClaimsSet.builder()\n            .issuer("self")  //Only this for simplicity\n            .build();\n    var encoder = jwtEncoder();\n    //This line throws the exception\n    String token = encoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();\n    System.out.println(token);\n\n    var decoder = jwtDecoder();\n    Jwt jwt = decoder.decode(token);\n    System.out.println(jwt.getIssuer());\n  }\n\n  public static void main(String[] args) throws JOSEException {\n    new EncoderDecoderTest().tester();\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

jps 已经给出了为什么这不起作用的解释(AES 不是有效的签名算法),谢谢:-)\n我想我的问题可以改写为:我如何实现这些的共享秘密版本两个编码器/解码器,例如使用 SHA-256 的 HMAC?

\n
org.springframework.security.oauth2.jwt.NimbusJwtDecoder\norg.springframework.security.oauth2.jwt.NimbusJwtEncoder\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试了(很多)但还没有成功;-(\n关于如何解决这个问题有什么建议吗?

\n

Pla*_*aul 13

根据 jps 的输入(AES 实际上可以用于加密令牌,但未签名)和 Github Copilot,我想出了一个使用 HMAC-SHA256 的可行解决方案:

//Don't hardcode like this for real
  public static String secret = "s/4KMb61LOrMYYAn4rfaQYSgr+le5SMrsMzKw8G6bXc=";

  public JwtEncoder jwtEncoder() throws JOSEException {
    SecretKey key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
    JWKSource<SecurityContext> immutableSecret = new ImmutableSecret<SecurityContext>(key);
    return new NimbusJwtEncoder(immutableSecret);
  }

  public JwtDecoder jwtDecoder() {
    SecretKey originalKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
    NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withSecretKey(originalKey).build();
    return jwtDecoder;
  }

  public void tester() throws JOSEException {
    //Create the TOKEN
    JwtClaimsSet claims = JwtClaimsSet.builder()
            .issuer("https://somewhere.com")  //Only this for simplicity
            .build();
    var encoder = jwtEncoder();
    JwsHeader jwsHeader = JwsHeader.with(() -> "HS256").build();
    String token = encoder.encode(JwtEncoderParameters.from(jwsHeader, claims)).getTokenValue();
    //Decode the TOKEN
    var decoder = jwtDecoder();
    Jwt jwt = decoder.decode(token);
    System.out.println(jwt.getIssuer());
  }
Run Code Online (Sandbox Code Playgroud)