firebase / php-jwt

PHP package for JWT
BSD 3-Clause "New" or "Revised" License
9.38k stars 1.27k forks source link

Why RSA private keys are not supported? #340

Open zablik opened 3 years ago

zablik commented 3 years ago

It's not an issue, but I need some help with my case.

I guess there should be a reason for this, but why RSA private keys are not supported? What can you recommend to use if I need to decode JWT using RSA private key, with this "d" key?

Thanks!

bshaffer commented 2 years ago

I believe you're referring to this line where an exception is thrown for private keys. The JWKs should be public keys, so the error is to provide guidance in case you accidentally supply a private key. If you have a use-case where the JWK contains both a private and public key, you should be able to simply unset "d" before parsing the key.

I'm open to removing the check if there's a good use case for doing so.

ots-georgewilkins commented 2 years ago

@bshaffer: I'm open to removing the check if there's a good use case for doing so.

I may be misunderstanding the intended workflow, but the RSA private key I'm testing with happens to be in the private+public JWK format, because this is the output of a tool recommended in a prior issue relating to parsing private keys:

@bshaffer: Try this tool: https://mkjwk.org/

@bshaffer: If you mean with this library, use parseKeySet:

// JSON string from jwk url
$jwk = '{"keys":[...]}';
$keys = Firebase\JWT\JWK::parseKeySet($jwk);
$privateKey = $keys['someKeyId'];

As far as I can see this isn't currently supported due to the aforementioned check; but also the parseKey/parseKeySet logic seems to be specific to public keys.

mkjwk.org "Public and Private Keypair":

{
    "p": "...",
    "kty": "RSA",
    "q": "...",
    "d": "...",
    "e": "AQAB",
    "use": "sig",
    "kid": "something",
    "qi": "...",
    "dp": "...",
    "alg": "RS512",
    "dq": "...",
    "n": "..."
}

I'm unclear on why the tool generates a combined private/public key structure. Presumably the public key attributes are required for the private key to parsed?

It sounds like the concerns regarding JWKS not containing private keys are warranted, so rather than removing the check altogether, could it be relocated to parseKeySet instead of parseKey?

This would permit a single private key to be parsed from the format, but a set to only ever contain public keys.