簡體   English   中英

"如何在 Java 中使用令牌和公鑰驗證 JWT 簽名"

[英]How to verify JWT signature using a token and public key in Java

我有一個字符串形式的令牌,我下載了公共證書並從中創建了一個公鑰,如下所示。

但我不確定如何使用這么多信息進行驗證。

我找到了 C# 和 .NET 的解決方案,但沒有找到 Java 的解決方案。 請注意,我沒有 jks 文件或私鑰。

    FileInputStream fin = new FileInputStream("d://public.crt");
    CertificateFactory f = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
    PublicKey pk = certificate.getPublicKey();

要使用 Auth0 庫 (com.auth0:java-jwt) 在 Java 中驗證 JWT:

  1. 檢索密鑰已簽名的算法,例如:

     // Load your public key from a file final PublicKey ecdsa256PublicKey = getPublicKey(...); final Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) ecdsa256PublicKey, null);
  2. 使用相應的算法驗證其簽名:

     final DecodedJWT decodedJWT = JWT.decode("JWT[...]"); // Will throw a SignatureVerificationException if the token's signature is invalid algorithm.verify(decodedJWT);

我做了這樣的事情來驗證 JWT

try {
        DecodedJWT decodedJWT = JWT.decode(jwt); // your string
        JwkProvider provider =  new JwkProviderBuilder(new URL("JWKS URL")).build();
        Jwk jwk = provider.get(decodedJWT.getKeyId());
        Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);

        Verification verifier = JWT.require(algorithm);
        verifier.build().verify(decodedJWT);
    } catch (JWTVerificationException | JwkException | MalformedURLException e) {
        // throw your exception
    }

JwkProviderBuilder可能很昂貴,因此如果您使用的是 Spring,您可以將其提取為另一種方法,並使用@PostConstruct對其進行注釋以進行優化。

使用 RSA 密鑰的工作示例如下所示:

/* Verification of JWT */
try {
    String token = "some-token";
    String publicKey = "some-key";
    
    //Convert public key string to RSAPublicKey
    byte[] publicKeyByteArr = Base64.getDecoder().decode(publicKey);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPublicKey rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyByteArr));

    //If the token has an invalid signature, JWTVerificationException will raise.
    Algorithm algorithm = Algorithm.RSA256(rsaPublicKey, null);
    JWTVerifier verifier = JWT.require(algorithm)
                //.withIssuer("auth0")
                .build(); //Reusable verifier instance
    DecodedJWT jwt = verifier.verify(token);

}catch(InvalidKeySpecException | NoSuchAlgorithmException | JWTVerificationException e) {
    logger.info("JWT verification is failed");
    throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
}

如果您詢問 JSON WebToken,您可以按照以下代碼示例進行操作:

import javax.xml.bind.DatatypeConverter;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Claims;

//Sample method to validate and read the JWT
private void parseJWT(String jwt) {

    //This line will throw an exception if it is not a signed JWS (as expected)
    Claims claims = Jwts.parser()         
       .setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret()))
       .parseClaimsJws(jwt).getBody();
    System.out.println("ID: " + claims.getId());
    System.out.println("Subject: " + claims.getSubject());
    System.out.println("Issuer: " + claims.getIssuer());
    System.out.println("Expiration: " + claims.getExpiration());
}

如需進一步閱讀,您可以訪問單擊此處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM