question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RS256 Token Validation & Decoding using Public Key Not Working "ValueError: Could not deserialize key data."

See original GitHub issue

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

  {
   "kty": "RSA",
   "alg": "RS256",
   "use": "sig",
   "kid": "8c9eb968f73744eaed421e48010142bce51a067f",
   "n": "uweJ3hFY9wqZ6ZG-iSNhQwHtKCGl8G_jcQgGPjOrS-Rum3dyDjicqkAyfS8XDn480KD_TZ5m-lqBjqfimePu2_cH4URDPIwsqSzJI2_piEhaqnXRptIe5YB5imAL6iETKaOPjw284Fc7EdHK-ekHMn3AXjsy9AIErwAVw4-4ZXXwHbyQXJy1DyUB4ZzxiEvw_qkQmLdltmrNkLOw-Xh-C9UkTZ9NA58bYPBnxLwnAu_ggw_g_-hCAs6OvXZbAfFHhIGBLyjtdDLVrfXo1112QREB9d5sEds0bKZtJcD9afl4E7Ht6G-g3jNP2clAu6-6B-cIe4-j8Ph1uJDPkAmDfw",
   "e": "AQAB"
  }

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

Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/jwt/algorithms.py", line 205, in prepare_key
    key = load_pem_private_key(key, password=None, backend=default_backend())
  File "/anaconda3/lib/python3.6/site-packages/cryptography/hazmat/primitives/serialization.py", line 20, in load_pem_private_key
    return backend.load_pem_private_key(data, password)
  File "/anaconda3/lib/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1015, in load_pem_private_key
    password,
  File "/anaconda3/lib/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1234, in _load_key
    self._handle_key_loading_error()
  File "/anaconda3/lib/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1292, in _handle_key_loading_error
    raise ValueError("Could not deserialize key data.")
ValueError: Could not deserialize key data.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/anaconda3/lib/python3.6/site-packages/jwt/api_jwt.py", line 93, in decode
    jwt, key=key, algorithms=algorithms, options=options, **kwargs
  File "/anaconda3/lib/python3.6/site-packages/jwt/api_jws.py", line 157, in decode
    key, algorithms)
  File "/anaconda3/lib/python3.6/site-packages/jwt/api_jws.py", line 221, in _verify_signature
    key = alg_obj.prepare_key(key)
  File "/anaconda3/lib/python3.6/site-packages/jwt/algorithms.py", line 207, in prepare_key
    key = load_pem_public_key(key, backend=default_backend())
  File "/anaconda3/lib/python3.6/site-packages/cryptography/hazmat/primitives/serialization.py", line 24, in load_pem_public_key
    return backend.load_pem_public_key(data)
  File "/anaconda3/lib/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1041, in load_pem_public_key
    self._handle_key_loading_error()
  File "/anaconda3/lib/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1292, in _handle_key_loading_error
    raise ValueError("Could not deserialize key data.")
ValueError: Could not deserialize key data.

Reproduction Steps

import jwt

IDjwt = <my id_token here>  # Decoding this with verify=False works correctly, so the problem isn't with the ID Token

GoogPubKey = b'uweJ3hFY9wqZ6ZG-iSNhQwHtKCGl8G_jcQgGPjOrS-Rum3dyDjicqkAyfS8XDn480KD_TZ5m-lqBjqfimePu2_cH4URDPIwsqSzJI2_piEhaqnXRptIe5YB5imAL6iETKaOPjw284Fc7EdHK-ekHMn3AXjsy9AIErwAVw4-4ZXXwHbyQXJy1DyUB4ZzxiEvw_qkQmLdltmrNkLOw-Xh-C9UkTZ9NA58bYPBnxLwnAu_ggw_g_-hCAs6OvXZbAfFHhIGBLyjtdDLVrfXo1112QREB9d5sEds0bKZtJcD9afl4E7Ht6G-g3jNP2clAu6-6B-cIe4-j8Ph1uJDPkAmDfw'

#Convert to Base64 (replace '-', '_' with '+', '/', respectively, and pad with '=' to make multiple of 4)
GoogPubKey = GoogPubKey.replace(b'-', b'+')
GoogPubKey = GoogPubKey.replace(b'_', b'/')
GoogPubKey += b'=='
len(GoogPubKey) % 4  # 0
GoogPubKey = b'-----BEGIN PUBLIC KEY-----\n' + GoogPubKey + b'\n-----END PUBLIC KEY-----'

decoded = jwt.decode(IDjwt, GoogPubKey, algorithms='RS256')

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

$ python -m jwt.help
{
  "cryptography": {
    "version": "2.1.4"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.4"
  },
  "platform": {
    "release": "17.4.0",
    "system": "Darwin"
  },
  "pyjwt": {
    "version": "1.6.4"
  }
}

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:13
  • Comments:19 (2 by maintainers)

github_iconTop GitHub Comments

46reactions
jpadillacommented, Jul 19, 2018

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')
19reactions
beaugoghcommented, Jul 16, 2019
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')

just fyi, a simpler approach also worked for me;

import jwt
IDjwt = <my id_token here>
decoded = jwt.decode(IDjwt, '', verify=False)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Could not deserialize key data on decoding JWT python
Its a good idea to use your RSA keys with OpenSSL: ... Use the authlib library, I never managed to decode keycloak tokens...
Read more >
RS256 Token Validation & Decoding using Public Key Not ...
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...
Read more >
Could not deserialize key data on decoding JWT python
I am using pyjwt library for decoding the JWT token. I got this error when I am decoding. The code was given in...
Read more >
raise ValueError(“Could not deserialize key data.”)
Explanation: Apple requires that ES256 algorithm is used when encoding. See here. Solution, use: jwt.encode(data, APPLE_SIGNIN_PRIVATE_KEY, ...
Read more >
Could Not Deserialize Key Data On Decoding Jwt ... - ADocLib
PS384. PS512. RS256. The id token can be decoded fine if I disable verification but won't verify using Public Key Not Working ValueError:...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found