Search code examples
javaoauth-2.0jwtjjwt

i'm having trouble creating a JWT with JJWT library


i'm having trouble creating a JWT with the JJWT library : https://github.com/jwtk/jjwt

I have followed the instructions and came up with this simple class:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Calendar;
import java.util.Date;

public class Test {
    public static void main(String[] args){

        Date date = new Date();
        Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR, 1);

        Date expirationDate = cal.getTime();

        String jws = Jwts.builder()
                .setSubject("user")
                .setId("1")
                .setIssuer("me")
                .setIssuedAt(new Date())
                .setExpiration(expirationDate)
                .setIssuedAt(date)
                .signWith(key)
                .compact();

        System.out.println("jws: "+ jws);
        decode(jws);
    }


    public static Jws<Claims> decode(String token){
        return Jwts.parser().setSigningKey(Keys.secretKeyFor(SignatureAlgorithm.HS256)).parseClaimsJws(token);
    }
}

when i run it, i get the output:

jws: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwianRpIjoiMSIsImlzcyI6InZpY3RvciIsImlhdCI6MTU3NjEwMTAyNiwiZXhwIjoxNTc2MTA0NjI2fQ.28JIsQSc273GT_qjyXEGjyh5KTJJ3thYVGQAa4ZQzvo

and the exception:

Exception in thread "main" io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
    at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:383)
    at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:513)
    at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:573)
    at Test.decode(Test.java:38)
    at Test.main(Test.java:33)

Also when i paste my jwt on this site : https://jwt.io/ it gives me the correct (i presume) header:

{
  "alg": "HS256"
}

and the correct payload:

{
  "sub": "user",
  "jti": "1",
  "iss": "victor",
  "iat": 1576100934,
  "exp": 1576104534
}

but it says the signature is invalid.

What am I doing wrong? How do i create the signature correctly?


Solution

  • Verification means, to check the signature against the same key (in case of symmetric algotrithms such as HS256) that was used when the token was created.

    In your code you use the convenience function:

    Keys.secretKeyFor(SignatureAlgorithm.HS256))
    

    which is creating a suitable key for the given algorithm. But you don't save the key anywhere in your token creation method and generate a new one when you check the token. That has to fail.

    Instead you have to save the generated key and use it in your verification call.

    Also, when you check your token on jwt.io, you need to provide the key used for creation in the input field under 'Verfify Signature' in the right column. Without knowing the key, the signature can't be verified.

    In any real usage scenario you would not create a new key for every token, but have instead one key that you might have stored on server side.