validate token without knowing the algorithm used

Issue #174 wontfix
Vinoj Mathew created an issue

Hi there,

I am trying to validate the token. So the input i have is

1) token

2) url to get the public key

I have to pass the JWSVerificationKeySelector to pass the keysource which is nothing but url.

When i get the token i am not sure which algorithm i need to use, unless I parse the token and get the algoritm and then pass to it. How do i override it

means : I only know token and url and will just pass to it. This will identify the algorithm and do the validate

Below is the code snippet.

I passed the algorithm type ahead of validating the token,and currently this is the only way I think I can validate. Is there any other way i can validate the token without knowing the algorithm

      JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;

   JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlg, keySource);

        jwtProcessor.setJWSKeySelector(keySelector);

        SecurityContext ctx = null;

        JWTClaimsSet claimsSet = jwtProcessor.process("token3", ctx);

thanks

Comments (10)

  1. Connect2id OSS

    Does the published JWK set associated an "alg" for each key?

    https://tools.ietf.org/html/rfc7517#section-4.4

    Not sure how good a security practise is to not have a previous contract on what JWS / JWE algs to expect.

    Otherwise you can create a RemoteJWKSet instance and keep it around for reuse, while creating the key selector on demand.

  2. Vinoj Mathew reporter

    Thanks i think it varies our jwks url will not get alg on it

    {"keys":[{ "kty":"RSA", "use":"sig", "kid":"xxxx", "x5t":"xxx", "n":"nnnn", "e":"xxx", "x5c":["sssss"]}]}

    Also from my understanding I cannot use RemoteJWKSet because it always look into the cache to get the data. if we have multiple tokens comming from different vendors the jwksurl will be different. Other wise I have to call explicity

                  DefaultResourceRetriever togetAlgorithmType = new DefaultResourceRetriever();
           Resource resource = togetAlgorithmType.retrieveResource(new URL("https://lxxxxxxx/keys"));
           JWKSet jwkSet = JWKSet.parse(resource.getContent());
           for (JWK key: jwkSet.getKeys()) {
    
                System.out.println(key.getAlgorithm());
                System.out.println(key.getKeyType());
                System.out.println(key.getKeyID());
                System.out.println(key.getKeyUse());
            } #
    

    Anyway I cant get the algorithm from jwsurl. The only way I can get is parse the token and get the algorithm form the header.

    Thanks VInoj

  3. Connect2id OSS

    If the "kty" is "RSA" then the algorithm can be one of the following:

    JWSAlgorithm.RS256
    JWSAlgorithm.RS384
    JWSAlgorithm.RS512
    JWSAlgorithm.PS256
    JWSAlgorithm.PS384
    JWSAlgorithm.PS512
    

    Regarding the JWKSource, keep one caching RemoteJWKSet around for each vendor (to benefit from its caching), and use it to create the selector on demand.

  4. Vinoj Mathew reporter

    Thanks totally understand

    yes if the kty is "RSA" the algorithm will be either one of the 6. But how do I know unless if I parse the token and get it from the header :)

    yes for the JWKSource i can keep one for each vendor. Thanks for explaining.

    Thanks Vinoj

  5. Connect2id OSS

    In your case just reuse the RemoteJWKSet because caching is critical for performance. Having to fetch HTTP data repeatedly just to verify a token can bog your app down.

    Don't worry about creating a new key selector, that is efficient.

  6. Log in to comment