-
-
Notifications
You must be signed in to change notification settings - Fork 694
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
RS256 Token Validation & Decoding using Public Key Not Working "ValueError: Could not deserialize key data." #359
Comments
The same issue. |
Try something like this: import jwt
from jwt.algorithms import RSAAlgorithm
IDjwt = <my id_token here> # Decoding this with verify=False works correctly, so the problem isn't with the ID Token
key_json = '{"kty": "RSA","alg": "RS256","use": "sig","kid": "4129db2ea1860d2e871ee48506287fb05b04ca3f","n": "sxorUSxfZZjQL1mDr1rtbNGJE9lbVMiBmNZFqLhnQaefTfqMO3YgSlb_cptw5wS2Dn4phGNzjBaO1Hg5572mEqsmPl5z9MmybIOuqWXxYyIiCGWH3hoR2VPJ-1bN-SdszHb4ZWadXCCYqnHS216nrvHZK8vJyQ7XCchw43O00LC5Iwi2eKspQEj8YDQSZFsd7Mp2ULhKXVPyKeLH06aenBZZFwgjw8bow7MXS4uUkg4NOeH2iHNxclOYycg6Z87QrTVzHGBo9r-6s1XRTFh-rqcZC8RnR62wkPqB2AEHctOof_ZtaaDTZ1Xw7db8dRhhCnFkpiK_1d8c9N2Vm7Frxw","e": "AQAB"}'
public_key = RSAAlgorithm.from_jwk(key_json)
decoded = jwt.decode(IDjwt, public_key, algorithms='RS256') |
Hi. Arrived here after searching for the past 6 hours on the solution. My eyes are bleeding. My token is minted in Keycloak as asymmetric RS256. Initial form retrieved from keycloak > realm > keys > rsa (and btw converted cert also matches public key), kid in the token matches kid in keycloak. its definitely the right key.
Above key is raw, without headers. I found out they must be present for the key to be valid as the Crypto is making it as far as https://github.com/pyca/cryptography/blob/master/src/cryptography/hazmat/backends/openssl/backend.py#L1029-L1052 and then kills conversion with error producing
I found that headers are quite important for decoding as decisions as to what decoder to use is based on the header. So tried all combinations, exactly like @tyrelkostyk "no header, begin public, begin rsa public and no go. For completion sending a token as well (to match against pasted key above)
Token is expired but the idea obviously to parse load public key instead before any other verifications. Two things: After this exercise i am certain I know far less than I thought I did. AND that this issue is most likely related to the formating of the public key. Decoding of token works fine obviously with verify=false |
jwt.io validates the key with -----BEGIN RSA PUBLIC KEY-----/-----END RSA PUBLIC KEY----- header styles hence in my case corresponds to PKCS#1 and going in, selected line represents last working line, everything fails on that check, This could still be a formatting issue as far as I suspect since online verifier at jwt.io was javascript based hence implemented differently. |
@jpadilla Out of 1000's of messages i've read today, your hint WORKED. @tyrelkostyk give up on passing public key yourself. Instead realy on OIDC well known config to discover exactly how you can construct RSA from JWK. It is there you don't have to guess it, at least it worked for me. Here is how I retrieved it. Find your well-known config endpoint that lists all other endpoints. In case of keycloak its here (obviously realm will be different) ..then load "certs" endpoint and then... use @jpadilla example above but with new token and detected jwk construction set
TADA.. Thank you!!! |
FYI: Openidc well.known endpoint for Azure: @tyrelkostyk and for Google: |
Just for reference, I'm also using keycloak and for me the issue was line breaks |
Thank you @jpadilla! I was stuck for a long time but then came across this post and now I am able to successfully verify JWT token issued by AWS Cognito User Pool using the same guidelines. Thanks once again! |
@vjsimha1 Indeed, this is the solution I came up with for decoding AWS Cognito tokens:
Does this look similar to your solution? |
I documented my process in this PR vimalloc/flask-jwt-extended#222 There is no point of making the call to JWK endpoint and then retrieve all elements independently since they can be fed all at once into the RSAAlgorithm and then that public key is ready to go for verification of signature. Its a two lines of code if you use something like this: https://github.com/vimalloc/flask-jwt-extended/blob/master/flask_jwt_extended/tokens.py#L115 |
same problem when trying to validate firebase tokens with the public key https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com works only with verify=False `
` |
just fyi, a simpler approach also worked for me; import jwt
IDjwt = <my id_token here>
decoded = jwt.decode(IDjwt, '', verify=False) |
We also faced the same problem. |
Just a note that I faced a similar issue and found a solution. In my case, I was using a signing certificate downloaded from Auth0 in PEM format, which I had incorrectly assumed was a public key. According to https://cryptography.io/en/latest/hazmat/primitives/asymmetric/serialization/#pem:
My PEM file did start with
Note that in this code, Now that I'm actually passing a public key into See also: https://community.auth0.com/t/token-validation-with-python/21589/2. |
This was exactly what i needed. i also struggled with keycloak. i had to make a small change to the jwt.decode though to make it working on my side: Thanks alot for this solution! |
I could get this working without a public/private key using options. decoded_details = jwt.decode(jwt_id_token, options={"verify_signature": False})
Note: "verify_signature": False is not recommended for production use. |
Working with IBM Cloud tokens, @jpadilla's suggestion above cleared the
|
@scottwn At least, you should use decoded = jwt.decode(token, public, algorithms=key['alg']) |
I'm trying to validate Google's ID Tokens for user authentication on a web app. The id token can be decoded fine if I disable verification, but won't verify when I pass it the RSA256 Public Key. The Public Key in question is Base64urlUInt-Encoded (RFC 7518 Specification).
The Entire Public Key Response
According to the Specification I linked above, the "n" parameter is the Modulus, and the "e" parameter is the exponent. I've tried absolutely every combination of decoding these to common Base64 format, but no matter what I do, pyJWT doesn't like it.
Expected Result
A Verified, decoded JSON data packet.
Actual Result
Reproduction Steps
Again, I've tried over a dozen different ways of using this RSA Public Key Google supplies, but nothing works (Using Base64url like they provide, using or not using the 'BEGIN PUBLIC KEY' prefix/suffix, type bytes or str, adding the "AQAB" prefix in multiple places, nothing works)
Any help would be greatly appreciated!! Thank you
System Information
The text was updated successfully, but these errors were encountered: