firebase / php-jwt

PHP package for JWT

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error when decoding a JWT with JWK set

nscarlato-ith opened this issue · comments

I am trying to decode a JWT with a JWK set and get the error "kid" invalid, unable to lookup correct key from JWT::getKey() for the following code:

$jwt = 'eyJraWQiOiIyMDE5LTA1LTIyVDIwOjQwOjM4Ljc4MS5lYyIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.[...]'
$keys = file_get_contents(self::JWK);
$jsonKeys = json_decode($keys, true);

// This filtering was needed otherwise when parsing the keys it would fail. I feel like it should fail and continue trying with other keys of the array...
$jsonKeys = array_filter(
    $jsonKeys['keys'],
    fn ($key) => isset($key['kty'])
        && isset($key['crv'])
        && $key['crv'] === self::JWT_ALGORITHM_CURVE
);

$jwtSet = JWK::parseKeySet(['keys' => $jsonKeys], 'ES256');
$decodedToken = (array) JWT::decode($jwt, $jwkSet);

I checked the JWT on JWT.io and I can see the 'kid' header.

I tried decoding with only one key changing the code to $decodedToken = (array) JWT::decode($jwt, array_shift($jwkSet)); and it worked fine. Same as when parsing keys, I believe it should be able to handle several keys (if one fails, try the others).

I don't think I am doing something wrong, but in case someone sees something odd please correct me.

Hi @nscarlato-ith !

This is not the intended behavior - there are two ways you can pass in keys/key sets for the library to properly decode them:

  1. The second argument to JWT::decode is a single instance of Key, which you know is the correct key to decode your JWT,
  2. The second argument to JWT::decode is a KeySet, with the Key ID as part of the key in the JWT header.

In both these cases, you tell this library which key your JWT is using - in the first case you pass only ONE key, in the second case, your JWT contains the correct Key Id to look up in the Key Set. There is no functionality for this library to "find which key is correct".

To do something like that, you'll need to iterate through all your keys and call decode until one of them works. See the Google API client libraries for an example of this.