firebase / php-jwt

PHP package for JWT

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Verifying JWK with one out of multiple keys, where one of the keys is a HS256 key

0xmerp opened this issue · comments

Hi,

Basically I have a use case where I would like to verify JWKs where the signature might be either one of a collection of ES256 keys (ECDSA), or a HS256 (Sha256-HMAC) key.

I was looking at this: https://github.com/firebase/php-jwt?tab=readme-ov-file#example-with-multiple-keys

This lets me load my JWK key set with all of my ES256 keys, but won't handle the case where the JWK might be signed with a HS256 key.

Here is an example of the use case: https://developers.line.biz/en/docs/line-login/verify-id-token/#signature

I was just wondering if php-jwt supports this use case, or if I could propose it as a feature.

Hello @0xmerp ! Thanks for the question.

where the signature might be either one of a collection of ES256 keys (ECDSA), or a HS256 (Sha256-HMAC) key.

This is possible, but ONLY if the JWT contains a kid in the header which identifies it's key. If you have this, then there's no reason you can't decode a JWT with either key.

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$keys = [
    'keyIdForHMACKey' => new Key('some-hmac-secret', 'HS256'),
    'keyIdForECDSAKey' => new Key('some-ecdsa-private-key', 'ES256'),
];

// the JWT header MUST contain `"kid": "keyIdForHMACKey"`, otherwise the library
// will not know which key to use
$jwt = JWT::encode(
    ['this' => 'is', 'a' => 'test payload'],
    $keys['keyIdForHMACKey']->getKeyMaterial(),
    'HS256',
    'keyIdForHMACKey' // the key ID is supplied here
);

$decoded = JWT::decode($jwt, $keys);
var_dump($decoded); // success!

Without setting the KID, there's no way in this library to do it. If you end up implementing this in your own way, be sure to avoid the "key/algorithm type confusion" security vulnerability (see GHSA-8xf4-w7qw-pjjw).

Please reopen this (or open a issue bug) if you have any more questions!