How to verify token signature in Nimbus JOSE + JWT

17,061

There is sample code to do this, but you have all the code in place to do this in your question.

For a shared key:

JWSVerifier verifier = new MACVerifier(sharedKey.getBytes());

If you're using an RSA keypair (as in your example), you need only supply the public key:

JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey);

Then ask it to verify the signature, noting that it will throw an exception if it's invalid:

boolean verifiedSignature = false;

    try {
      JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey);
      verifiedSignature = signedJWT.verify(verifier);
    }
    catch (JOSEException e) {
      System.err.println("Couldn't verify signature: " + e.getMessage());
    }

A complete method to do check token signature might look like this:

public static boolean isSignatureValid(String token) {
    // Parse the JWS and verify its RSA signature
    SignedJWT signedJWT;
    try {
        signedJWT = SignedJWT.parse(token);
        JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey);
        return signedJWT.verify(verifier);
    } catch (ParseException | JOSEException e) {
        return false;
    }
}
Share:
17,061
kittu
Author by

kittu

Worked on different stack of technologies with 6+ years of experience such as: Front-end stack: Javascript, Angular 7/8, HTML5/CSS3, Bootstrap Back-end stack: NodeJs, MongoDb with mongoose, AWS, RabbitMQ Tools: Git, VS Code, Jenkins Passionate about working on enterprise or product based companies with react, node and mongo tech stack

Updated on July 22, 2022

Comments

  • kittu
    kittu almost 2 years

    I have tokens going back and forth from server to client on each request for resource using Nimbus JOSE + JWT

    Code for creating JWT token:

    public class TokenProvider {
    
        String token = "";
    
        public String getToken(String email) {
            try {
                KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA");
                keyGenerator.initialize(1024);
    
                KeyPair kp = keyGenerator.genKeyPair();
                RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
                RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
    
                System.out.println("publicKey: " + publicKey);
                System.out.println("privateKey: " + privateKey.toString());
    
                JWSSigner signer = new RSASSASigner(privateKey);
    
                JWTClaimsSet claimsSet = new JWTClaimsSet();
                claimsSet.setSubject("RTH");
                claimsSet.setCustomClaim("email", email);
                claimsSet.setCustomClaim("role", "USER");
                claimsSet.setIssuer("https://rth.com");
                claimsSet.setExpirationTime(new Date(new Date().getTime() + 60 * 1000));
    
                SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet);
    
                signedJWT.sign(signer);
                token = signedJWT.serialize();
                TokenSaverAndValidatorDAO tokenSaver = new TokenSaverAndValidatorDAO();
                tokenSaver.saveTokenToDB(email, token);
    
                signedJWT = SignedJWT.parse(token);
    
                JWSVerifier verifier = new RSASSAVerifier(publicKey);
                System.out.println("verifier: " + verifier);
                System.out.println("verify method: " + signedJWT.verify(verifier));
                assertTrue(signedJWT.verify(verifier));
                assertEquals("RTH", signedJWT.getJWTClaimsSet().getSubject());
                assertEquals("https://rth.com", signedJWT.getJWTClaimsSet().getIssuer());
                assertTrue(new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime()));
            } catch (JOSEException | ParseException | NoSuchAlgorithmException ex) {
                Logger.getLogger(TokenProvider.class.getName()).log(Level.SEVERE, null, ex);
            }
            return token;
        }
    }
    

    So far its working fine but the problem is how do I verify the token signature received back from client?

    From the API, there is only one method which looks like it is for verification but its accepting only public Key (RSAPublicKey) as parameter rather than token.

    Anyone worked on JWT using this library please help. Thank you