'How to verify JWT signature using a token and public key in Java
I have a token in the form of a string and I downloaded the public cert and created a public key out of it as follows.
But I'm not sure how proceed for verification with just this much info.
I found solutions for C# and .NET but not for Java. Please note I don't have the jks file or private key.
FileInputStream fin = new FileInputStream("d://public.crt");
CertificateFactory f = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
PublicKey pk = certificate.getPublicKey();
Solution 1:[1]
To verify a JWT in Java using Auth0 library (com.auth0:java-jwt):
Retrieve the algorithm the key has been signed with, for example:
// Load your public key from a file final PublicKey ecdsa256PublicKey = getPublicKey(...); final Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) ecdsa256PublicKey, null);Verify its signature using the corresponding algorithm:
final DecodedJWT decodedJWT = JWT.decode("J.W.T[...]"); // Will throw a SignatureVerificationException if the token's signature is invalid algorithm.verify(decodedJWT);
Solution 2:[2]
I did something like this to verify 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 can be expensive, so if you are using Spring, you can extract it as another method and annotate it with @PostConstruct to optimise.
Solution 3:[3]
A working example with RSA key is as given below:
/* 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);
}
It's obvious but please note that token and publicKey are arbitrary.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Florian Lopes |
| Solution 2 | |
| Solution 3 | Sezerb |
