Developer
Developer

Reputation: 168

Verify Access token signature using java-jwt

I am trying to validate JWT Access token which generated by KeyCloak Authorization server.

I have copied public_key from http://ip-address:port/auth/realms/

For validating Access token i am using https://mvnrepository.com/artifact/com.auth0/java-jwt

and referring https://www.baeldung.com/java-jwt-token-decode for verifying signature.

Code I am trying:

 String publicKey =<public_key from http://<ip>:<port>/auth/realms/<app> >
 
 String accessToken =<valid access token from keycloak>
  
 String[] chunks = accessToken.split("\\.");
 
 Base64.Decoder decoder = Base64.getDecoder();
 String header = new String(decoder.decode(chunks[0]));  // {"alg":"RS256","typ" : "JWT","kid" : "dsssdssdf"}
 String payload = new String(decoder.decode(chunks[1])); //{"exp":1632237161,"iat":1632236861,"auth_time":1632236854,"jt..."}
 String signature = chunks[2]; // <signature from access token>
 
 SignatureAlgorithm sa = SignatureAlgorithm.RS256;
 String tokenWithoutSignature = chunks[0] + "." + chunks[1];
 SecretKeySpec secretKeySpec = new SecretKeySpec(publicKey.getBytes(), sa.getJcaName());
 
 DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);
 
 if (!validator.isValid(tokenWithoutSignature, signature)) {
      System.out.println("=============== Invalid access token");
    } else {
      System.out.println("============= valid access token");
    }

After running above code following error observed:

java.lang.IllegalArgumentException: RSA Signature validation requires either a RSAPublicKey or RSAPrivateKey instance.
    at io.jsonwebtoken.lang.Assert.isTrue(Assert.java:38)
    at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.<init>(RsaSignatureValidator.java:36)
    at io.jsonwebtoken.impl.crypto.DefaultSignatureValidatorFactory.createSignatureValidator(DefaultSignatureValidatorFactory.java:43)
    at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.<init>(DefaultJwtSignatureValidator.java:37)
    at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.<init>(DefaultJwtSignatureValidator.java:32)
    

Can anyone please help here?

Upvotes: 1

Views: 4255

Answers (1)

Developer
Developer

Reputation: 168

I try something like :

String publicKey =<public_key from http://<ip>:<port>/auth/realms/<app> >
byte[] decoded = Base64.getDecoder().decode(publicKey);

String algorithm = "RSA";
KeyFactory kf = KeyFactory.getInstance(algorithm);
PublicKey generatedPublic = kf.generatePublic(new X509EncodedKeySpec(decoded));

String accessToken =<valid access token from keycloak> 
String[] chunks = accessToken.split("\\.");

Base64.Decoder decoder = Base64.getDecoder();

String header = new String(decoder.decode(chunks[0]));  // {"alg":"RS256","typ" : "JWT","kid" : "dsssdssdf"}
String payload = new String(decoder.decode(chunks[1])); //{"exp":1632237161,"iat":1632236861,"auth_time":1632236854,"jt..."}
String signature = chunks[2]; // <signature from access token>

SignatureAlgorithm sa = SignatureAlgorithm.RS256;
String tokenWithoutSignature = chunks[0] + "." + chunks[1];

DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, generatedPublic);

if (!validator.isValid(tokenWithoutSignature, signature)) {
           System.out.println("=============== Invalid access token");
} else {
          System.out.println("============= valid access token");
}

and It worked !!

Upvotes: 1

Related Questions