Verification key for jose4j JwtConsumer

Wang Sheng picture Wang Sheng · Aug 3, 2015 · Viewed 9.1k times · Source

I am using jose4j to validate and process a JWT. The JWT looks like the following and it passes the validation in the JWT homepage. enter image description here

However, I can't do the same using jose4j java library. The exception complains about the verification key I set. But there are many types of keys defined in the library and I tried them but no luck. The code is as following:

import java.util.Map;

import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.keys.HmacKey;

public class YGJWT {

    public static void main(String args[]) throws InvalidJwtException {

        String jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
        String secret = "secret";

        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                .setVerificationKey(new HmacKey(secret.getBytes())) //what kind of key do i need to use it here?
                .build();


        JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
        Map<String, Object> claimsMap = jwtClaims.getClaimsMap();

        claimsMap.forEach((String key, Object val) -> {
            System.out.println(key + ": " + val.toString());
        });

    }

}

Any help is appreciated.

Answer

Brian Campbell picture Brian Campbell · Aug 3, 2015

I 'd guess you're getting an Exception something like this? org.jose4j.lang.InvalidKeyException: A key of the same size as the hash output (i.e. 256 bits for HS256) or larger MUST be used with the HMAC SHA algorithms but this key is only 48 bits

The HmacKey is the correct type for HS256 but the key is technically too short according to the second paragraph of https://www.rfc-editor.org/rfc/rfc7518#section-3.2 which has the same text as the exception message.

You can work around it by building the JwtConsumer with .setRelaxVerificationKeyValidation(), which will allow for shorter keys. That looks like this (adding just one line to a snippet from your example):

  JwtConsumer jwtConsumer = new JwtConsumerBuilder()
     .setVerificationKey(new HmacKey(secret.getBytes())) 
     .setRelaxVerificationKeyValidation() // allow shorter HMAC keys when used w/ HSxxx algs 
     .build();

In general though I would try and avoid the use of a short password like key such as "secret" and suggest using a stronger key when possible.