I am using pyjwt library for decoding the JWT token. I got this error when I am decoding. The code was given in the documantation.
import jwt
encoded_jwt=\'
If you get this error double check your public key is exactly right, new lines are important.
key = '''-----BEGIN PUBLIC KEY-----
<main key here>
-----END PUBLIC KEY-----'''
MacOS Catalina 10.15.4 Python 2.7.16.
This solved the problem in my case
pip install cryptography==2.3
Use the authlib library, I never managed to decode keycloak tokens with pyjwt
.
You need a public_key
, I assume you have it.
from authlib.jose import jwt
key = '-----BEGIN PUBLIC KEY-----\n' + public_key + '\n-----END PUBLIC KEY-----'
key_binary = key.encode('ascii')
try:
claims = jwt.decode(encoded,key_binary)
claims.validate()
#do some logic here
#...
ProTip: you may grab the public key easily from your auth server (in my case Keycloak) at some endpoint:
url = 'http://localhost:8080/auth/realms/your_realm'
with urllib.request.urlopen(url) as r:
response = r.read()
public_key = json.loads(response)['public_key']
Its a good idea to use your RSA keys with OpenSSL:
openssl genrsa -out jwt-key 4096
openssl rsa -in jwt-key -pubout > jwt-key.pub
Reference: link
There are some issues in the pyjwt library. and you must get the public key from the certificate.
I used openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
then from the public key I could easily decode it using authlib library.
from authlib.specs.rfc7519 import jwt
encoded_jwt='''eyJ0eXAiOiJ....'''
secret=b'''-----BEGIN PUBLIC KEY-----
......
-----END PUBLIC KEY-----'''
claims = jwt.decode(encoded_jwt, secret)
print(claims)
How did you encode your jwt? Use one of the approaches below
Encoding & Decoding Tokens with RS256 (RSA)
encoded = jwt.encode({'some': 'payload'}, private_key, algorithm='RS256')
decoded = jwt.decode(encoded, public_key, algorithms='RS256')
Reading the Claimset without Validation
jwt.decode(encoded, verify=False)
{u'some': u'payload'}
Or use same secret to encode and decode the jwt, one of the approach should work. In my case I used jwt.decode(token, verify=False)
because my server has already did the signature validation for me, I only need to get the claimset.