Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't verify detached payload JWS with JWK from its header #851

Open
AFlowOfCode opened this issue Jan 16, 2023 · 4 comments
Open

Can't verify detached payload JWS with JWK from its header #851

AFlowOfCode opened this issue Jan 16, 2023 · 4 comments
Labels

Comments

@AFlowOfCode
Copy link

I am trying to verify the signature of a JWS with the JWK that is included in its header. I believe the fact that it has a detached payload is only incidental to the primary issue of not recognizing the correct form of a JWS's key. The JWK is normal and valid, for example:

{'crv': 'P-256', 'kty': 'EC', 'x': 'PY5pUvmWTEz5mCVir-Tyfi1M0q07_qaZSU_UAN3HBSI', 'y': 'aH9ZAGpTidZjxNu2zKXeX9koNQX_BAtIBCa-h7YC_B0'}

I can get a jwt.api_jwk.PyJWK object if I do api_jwk.PyJWK(jws_jwk, algorithm='ES256') , proving there is no issue with the JWK itself.
However when I try to use it to verify the signature of a JWS in the manner below, I receive the error message Expecting a PEM-formatted key.

payload = api_jws.decode(
    jws_compact, verification_jwk, algorithms=['ES256'], 
    options={'verify_signature': True},
    detached_payload=payload)

It's clear that this is because the prepare_key method of the ECAlgorithm class expects either a key of type EllipticCurvePublicKey or a PEM string. However this is not how one typically receives the verification key in a JWS. They are always in JWK form, and I can't find any clear way to convert a JWK to a EllipticCurvePublicKey object nor a PEM.

Is this intended? Am I missing something obvious here? This seems like a bug or an oversight to me, so I appreciate any clarification on the proper verification of a JWS using its own key material.

Expected Result

To verify a standard JWS using the included key material, wherein it passes or fails depending upon the validity of the included signature as verified by the standard JWK included in a JWS protected header.

Actual Result

I am asked for a PEM-formatted key, which is not how keys are sent with a JWS.

Reproduction Steps

Use the JWK in any JWS and pass it into api_jws.decode along with the JWS as shown above.

@github-actions
Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the stale Issues without activity for more than 60 days label Mar 18, 2023
@jpadilla jpadilla added keep and removed stale Issues without activity for more than 60 days labels Mar 18, 2023
@jaferrando
Copy link

As a workaround I'd say you could load the JWK into a PyJWK object and then access the key atribute of the resulting object.

(untested code):

jwk_data = {'crv': 'P-256', 'kty': 'EC', 'x': 'PY5pUvmWTEz5mCVir-Tyfi1M0q07_qaZSU_UAN3HBSI', 'y': 'aH9ZAGpTidZjxNu2zKXeX9koNQX_BAtIBCa-h7YC_B0'}
jwk = PyJWK(jwk_data)
payload = api_jws.decode(
    jws_compact, jwk.key, algorithms=['ES256'], 
    options={'verify_signature': True},
    detached_payload=payload)

@AFlowOfCode
Copy link
Author

Nice, that does work. In that case it seems like updating the api_jws.decode method to handle actual JWKs could be implemented pretty easily. The conversion performed by PyJWK.key could be called on the verification material argument when the type is a dict instead of a PEM string or EllipticCurvePublicKey instance.

@auvipy
Copy link
Collaborator

auvipy commented Nov 8, 2023

I am open to review any contribution which fix this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants