I recently upgraded from PyJWT 0.4.1 to 1.0.1 and I can't figure out how to verify a JWT signed with a public key.
My code looks like this:
import jwt
cert_string = "-----BEGIN CERTIFICATE-----\nMIICITCCAYqgAwIBAgIIBEsUSxL..."
token_string = "eyJhbGciOiJSUzI1NiIsImtpZCI6I..."
jwt.decode(token_string, cert_string, algorithms=['RS256'])
The error I get is:
File "<stdin>", line 1, in <module>
File "~/.virtualenvs/project/lib/python2.7/site-packages/jwt/api.py", line 117, in decode
key, algorithms, **kwargs)
File "~/.virtualenvs/project/lib/python2.7/site-packages/jwt/api.py", line 176, in _verify_signature
key = alg_obj.prepare_key(key)
File "~/.virtualenvs/project/lib/python2.7/site-packages/jwt/algorithms.py", line 165, in prepare_key
key = load_pem_public_key(key, backend=default_backend())
File "~/.virtualenvs/project/lib/python2.7/site-packages/cryptography/hazmat/primitives/serialization.py", line 24, in load_pem_public_key
return backend.load_pem_public_key(data)
File "~/.virtualenvs/project/lib/python2.7/site-packages/cryptography/hazmat/backends/multibackend.py", line 285, in load_pem_public_key
return b.load_pem_public_key(data)
File "~/.virtualenvs/project/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 716, in load_pem_public_key
self._handle_key_loading_error()
File "~/.virtualenvs/project/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 912, in _handle_key_loading_error
raise ValueError("Could not unserialize key data.")
ValueError: Could not unserialize key data.
I'm confident my cert_string and token are good. The following code runs OK:
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
load_pem_x509_certificate(cert_string, default_backend())
My code that used to work with 0.4.1 looked like this:
cert_string = "".join(cert_string.strip().split("\n")[1:-1])
der = a2b_base64(cert_string)
cert = DerSequence()
cert.decode(der)
tbsCertificate = DerSequence()
tbsCertificate.decode(cert[0])
subjectPublicKeyInfo = tbsCertificate[6]
pub_key = RSA.importKey(subjectPublicKeyInfo)
jwt.decode(token_string, pub_key)
Any help would be appreciated.
To verify JWT claimsVerify that the token is not expired. The aud claim in an ID token and the client_id claim in an access token should match the app client ID that was created in the Amazon Cognito user pool. The issuer ( iss ) claim should match your user pool.
The library PyJWT has an option to decode a JWT without verification: Without this option, the decode function does not only decode the token but also verifies the signature and you would have to provide the matching key. And that's of course the recommended way.
JSON Web Tokens, or JWTs for short, are all over the web. They can be used to track bits of information about a user in a very compact way and can be used in APIs for authorization purposes. This post will cover what JSON Web Tokens are and how to create JWTs in Python using the most popular JWT library: PyJWT.
You need to pass the public key instead of the full certificate to the decode method. So extract the key from the certificate in order to use it as in:
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
cert_str = "-----BEGIN CERTIFICATE-----MIIDETCCAfm..."
cert_obj = load_pem_x509_certificate(cert_str, default_backend())
public_key = cert_obj.public_key()
and then:
token_string = "eyJhbGciOiJSUzI1NiIsImtpZCI6I..."
jwt.decode(token_string, public_key, algorithms=['RS256'])
If the key file is generated using ssh-keygen -t rsa
(RFC4716), you can use the file directly.
Encode:
import jwt
pemfile = open("id_rsa", 'r')
keystring = pemfile.read()
pemfile.close()
token = jwt.encode(payload, keystring, algorithm='RS256')
Decode:
import jwt
pemfile = open("id_rsa.pub", 'r')
keystring = pemfile.read()
pemfile.close()
payload = jwt.decode(toekn, keystring, verify=True)
dont forget to catch errors like jwt.ExpiredSignatureError
etc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With