1

I have created a JWT object with some data. Then I decode that same JWT object just to compare and see if the validation passes. But it does not. Following is the code I have created. What could be the issue?

              SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
              //Make a JWT Token String

              String jws = Jwts.builder().setSubject("adam")
               .setExpiration(new java.util.GregorianCalendar(2021, 
                                                        Calendar.NOVEMBER, 8).getTime())
               .setIssuer("someUser@mycompany.com")
               .claim("groups", new String[] { "user", "admin" })

                // HMAC using SHA-512  and 12345678 base64 encoded
                .signWith(signatureAlgorithm, "MTIzNDU2Nzg=").compact();

              System.out.println("JWTS String: "+ jws.toString());

              //=================================================
              //Decode the string back           
              Base64.Decoder decoder = Base64.getDecoder();
              String[] chunks = jws.split("\\.");
              String header = new String(decoder.decode(chunks[0]));
              String payload = new String(decoder.decode(chunks[1]));
              String signature = chunks[2];
             
              System.out.println("Header: " + header);
              System.out.println("PayLoad: " + payload);
              System.out.println("Signature: " + signature);

              String tokenWithoutSignature = chunks[0] + "." + chunks[1];
              SecretKeySpec secretKeySpec = new
                SecretKeySpec("MTIzNDU2Nzg=".getBytes(),signatureAlgorithm.getJcaName());
              DefaultJwtSignatureValidator validator = new
                DefaultJwtSignatureValidator(signatureAlgorithm,secretKeySpec);

              if (validator.isValid(tokenWithoutSignature, signature)){
                    System.out.println("TOKEN IS VALID");
              }else{
                    System.out.println("TOKEN IS INVALID");
              }
prain99
  • 21
  • 5
  • does your token have an expiration? – Stultuske Nov 08 '21 at 13:32
  • What is the result of `GregorianCalendar(2021, Calendar.NOVEMBER, 8).getTime()` ? Isn't it just the current time? If you set the expiration time like this, your token will always be expired. Instead use something like current time + x minutes, and without setting a fixed date. Can you pls. add the actual token to the question? – jps Nov 08 '21 at 13:38
  • I modified the expiration date by adding 10 minutes. But still the validation fails. ```Long currentTime = java.lang.System.currentTimeMillis();``` ```Date expirationDate = new Date( currentTime + 600000);``` ```logger.info("currentTime: "+ currentTime);``` ```String jws = Jwts.builder().setSubject("adam") .setExpiration(expirationDate) ``` – prain99 Nov 08 '21 at 16:26
  • Please share your token, so we can see if the exp is s correct unix timestamp in seconds. – jps Nov 08 '21 at 16:36
  • I ran the verifier in jwt.io/#encoded-jwt using the secure string eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZGFtIiwiZXhwIjoxNjM2NDAzOTYzLCJpc3MiOiJzb21lVXNlckBteWNvbXBhbnkuY29tIiwiZ3JvdXBzIjpbInVzZXIiLCJhZG1pbiJdfQ.lpy7bAGHrJ40t75Pr8CpdS4rVgDs9SvyXo3NKaXqEio created in the above code (String jws). The verifire tool says Signarure Verified. I do not understand why the validator.isValid () brings me false. Here is the token contents. ```{ "alg": "HS256" }``` { "sub": "adam", "exp": 1636403963, "iss": "someUser@mycompany.com", "groups": [ "user", "admin" ] } – prain99 Nov 08 '21 at 21:29
  • Actually, the timestamp seem off. I printed the time stamp during program execution is it was 1636403963193, but the exp: 1636403963 in the token has dropped last 3 digits????? – prain99 Nov 08 '21 at 21:36
  • The timestamp in the token is correct, as mentioned above it's a UNIX Timetamp in seconds since 1970/01/01 00:00 UTC. Your number is in milliseconds. Don't know how you got a verified signature, I could not verify the signature with the given secret that you show in your question. Please read [here](https://stackoverflow.com/questions/69862105/jwt-io-says-signature-verified-even-when-key-is-not-provided) how you can verify a signature on jwt.io (and avoid the most common error that lets you believe you verified, even when the secret is wrong) – jps Nov 08 '21 at 21:48
  • I agree. I did that in the wrong order at jwt.io. But my biggest concern is why isValid() method return false in spite of hardcoding the right secret and feeding correct algorithm. – prain99 Nov 09 '21 at 15:20

1 Answers1

0

You need to base64 decode the secret first.

replace...

SecretKeySpec secretKeySpec = new SecretKeySpec("MTIzNDU2Nzg=".getBytes(),signatureAlgorithm.getJcaName());

with

SecretKeySpec secretKeySpec = new SecretKeySpec(TextCodec.BASE64.decode("MTIzNDU2Nzg="), signatureAlgorithm.getJcaName());

and it should work!