JWT decoding say invalid signature even on providing correct "signing" key

JWT tokenization is driving me crazy or I am using it wrong.

To test out and start with "jjwt", i am creating a simple jwt token, below is the code.

static String createSimpleJWT() {
        String id, issuer, subject;
        id="id";
        issuer="issuer";
        subject="subject";

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id)
                .setSubject(subject)
                .setIssuer(issuer)
                .signWith(SignatureAlgorithm.HS256, "signingKey");  //plz note signing key on this line
        return builder.compact();
}

The jwt token is

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJpZCIsInN1YiI6InN1YmplY3QiLCJpc3MiOiJpc3N1ZXIifQ._7QGamE-HvREDMJIgbfKEIRv76ZaxwIx2t3RaViSYzth4

As intended, on subsequent executions also I get the same JWT.

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJpZCIsInN1YiI6InN1YmplY3QiLCJpc3MiOiJpc3N1ZXIifQ._7QGE-HvREDMJIgbfKEIRv76ZaxwIx2t3RaViSYzth4

I am decoding it using jwt.io to test - but am suprised to see that the jwt token is flaged with Invalid Signature inspite of providing the correct signing key in the decode section.

Here is jwt.io screenshot - jwt.io-invalidsignature

Any pointers... where it's getting messed.

This post is different from what's asked earlier where the users forgot or were not aware about providing signing key to jwt.io PHP JWT Token Invalid Signature
JWT Token Invalid Signature

2 answers

  • answered 2018-01-11 07:56 Gulliva

    I had nearly the same issue with this JWT lib so I changed it to another one. Don't know why this happens. My Application is used to authenticate against a third party system.

    Try this Lib an check it again, perhaps this helps you:

    https://github.com/auth0/java-jwt

  • answered 2018-01-11 08:54 pedrofb

    Your issue is similar to this https://stackoverflow.com/a/38269014/6371459.

    It is due to .signWith(SignatureAlgorithm.HS256, "secret"). It is implemented by DefaultJwtBuilder class

    public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) 
    

    This method assumes that you are providing a key in base64 and secret is not base64. When the method decodes from base64 to byte[] the java converter used by jjwt provides a representation of the string secr which is different to the JavaScript decoder used at jwt.io

    JWTBuilder.signWith requires a base64 encoded key, but you are providing a plain text, so:

    • Insert "signingK" and check "secret base64 encoded" in jwt.io

    • Provide a base64 encoded password

    --

    String signingKeyB64= Base64.getEncoder().encodeToString("signingKey".getBytes("utf-8"));
    JwtBuilder builder = Jwts.builder().setId(id)
                    .setSubject(subject)
                    .setIssuer(issuer)
                    .signWith(SignatureAlgorithm.HS256, signingKeyB64);
    

    I recommend to generate a random password instead of using a fixed string

    Key key = MacProvider.generateKey();
    String signingKeyB64 = Base64.getEncoder().encodeToString(key.getEncoded());