I getting Expecting a PEM-formatted key

I am trying to validate the JWT token in the backend but I am getting an “Expecting a PEM-formatted key.” error.

Here is my code:

import jwt

import json

from six.moves.urllib.request import urlopen

AUTH0_DOMAIN = 'mahdi-vanna.au.auth0.com'

algorithm = ['RS256']

jsonurl = urlopen("https://"+AUTH0_DOMAIN+"/.well-known/jwks.json")

jwks = json.loads(jsonurl.read())

rsa_key = {}

for key in jwks["keys"]:

    rsa_key = {

        "kty": key["kty"],

        "kid": key["kid"],

        "use": key["use"],

        "n": key["n"],

        "e": key["e"]

    }

token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkZ6TGxpb3hRc1hta3hxVFQyc0VudSJ9.eyJuaWNrbmFtZSI6Im0udmFsaXphZGVoNjgiLCJuYW1lIjoibS52YWxpemFkZWg2OEBnbWFpbC5jb20iLCJwaWN0dXJlIjoiaHR0cHM6Ly9zLmdyYXZhdGFyLmNvbS9hdmF0YXIvNTM1MDA4YzM4ZjViNzU3ZWE4Njc4OTBlNzg5ZmY0ZDg_cz00ODAmcj1wZyZkPWh0dHBzJTNBJTJGJTJGY2RuLmF1dGgwLmNvbSUyRmF2YXRhcnMlMkZtLnBuZyIsInVwZGF0ZWRfYXQiOiIyMDIwLTEwLTIzVDA0OjE5OjQ0Ljk5M1oiLCJlbWFpbCI6Im0udmFsaXphZGVoNjhAZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJpc3MiOiJodHRwczovL21haGRpLXZhbm5hLmF1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1ZjkyNTllMDNjM2Y5NjAwNjlhODliZmYiLCJhdWQiOiJab3JLUUhSTXdhckNzNUcyVXRDSlRPMEhVS2RCUGxmaSIsImlhdCI6MTYwMzQyNzcwNiwiZXhwIjoxNjAzNDYzNzA2LCJub25jZSI6ImIzSjBibGs1YVg1a2VHdEVNelkzTm1wV2VtMVlWMnhUYVRsbmJ6RjFSa3BIWDJsTU0zVm9NMU56TkE9PSJ9.QrVYdiE6UJHHlUFMudExH1gPrnHnIq2X2PuipbMV1JoAzME2s-V4xEd_1FZ6UX8qj_TO0iYbej3sPISBEm_l2A78noRM9HW9pGMnBaTht64leQsBBReB17gZsKoUkVFn7gFVqZy1SayVuptzVbKTkuX2Zt7pgnzas7iP1JC3QACBaDoC4bWEoVscN4AxGCp0rOJGWN18MA1RinFoiuRKayx1qPdh0BJkjxn6Vd303ppS223rUamhaxVBwmtROOE1t7UBqm5-bgdEpLoIc-nQrQAbpcW8r8-nkxkCQQsdUGaYvL_Wolcxz-gc92PmoOn0PzXubIiVqTzzxjxsOEFPXw'

decoded = jwt.decode(token, rsa_key, algorithms=algorithm,

                     issuer="https://"+AUTH0_DOMAIN+"/")

print(decoded)

And here is the error:

$ python myjwt.py
Traceback (most recent call last):
  File "myjwt.py", line 26, in <module>
    decoded = jwt.decode(token, rsa_key, algorithms=algorithm,
  File "C:\Users\Mahdi\.virtualenvs\auth0--EflSy7_\lib\site-packages\jwt\api_jwt.py", line 91, in decode
    decoded = super(PyJWT, self).decode(
  File "C:\Users\Mahdi\.virtualenvs\auth0--EflSy7_\lib\site-packages\jwt\api_jws.py", line 155, in decode
    self._verify_signature(payload, signing_input, header, signature,
  File "C:\Users\Mahdi\.virtualenvs\auth0--EflSy7_\lib\site-packages\jwt\api_jws.py", line 220, in _verify_signature
    key = alg_obj.prepare_key(key)
  File "C:\Users\Mahdi\.virtualenvs\auth0--EflSy7_\lib\site-packages\jwt\algorithms.py", line 209, in prepare_key
    raise TypeError('Expecting a PEM-formatted key.')
TypeError: Expecting a PEM-formatted key.
(auth0)

Hi @Mahdi

Welcome to the Community!

It looks like you are using the python quickstart, but switched which JWT library you are using.

Try using the jose library that is listed in the quickstart and see if that solves the issue.

1 Like

@dan.woda Thanks for the reply, I am getting the jose.exceptions.JWTError: Signature verification failed. error.

Could you please give me a document so I can see how should I configure Auth0 for my use case?
I need to create a backend that is able to extract data from token and save it somewhere

Did you change your code? Can you post what you are working with?

Thanks for helping, I changed my code as follows, it is working now, thanks.

from jose import jwt

import json

from six.moves.urllib.request import urlopen

from os import environ as env
from dotenv import load_dotenv, find_dotenv



ENV_FILE = find_dotenv()
if ENV_FILE:
    load_dotenv(ENV_FILE)
AUTH0_DOMAIN = env.get("AUTH0_DOMAIN")
API_IDENTIFIER = env.get("API_IDENTIFIER")
ALGORITHMS = ["RS256"]


# Format error response and append status code.
class AuthError(Exception):
    def __init__(self, error, status_code):
        self.error = error
        self.status_code = status_code


def get_token_auth_header(raw_token):
    """Obtains the access token from the Authorization Header
    """
    auth = raw_token
    if not auth:
        raise AuthError({"code": "authorization_header_missing",
                        "description":
                            "Authorization header is expected"}, 401)

    parts = auth.split()

    if parts[0].lower() != "bearer":
        raise AuthError({"code": "invalid_header",
                        "description":
                            "Authorization header must start with"
                            " Bearer"}, 401)
    elif len(parts) == 1:
        raise AuthError({"code": "invalid_header",
                        "description": "Token not found"}, 401)
    elif len(parts) > 2:
        raise AuthError({"code": "invalid_header",
                        "description":
                            "Authorization header must be"
                            " Bearer token"}, 401)

    token = parts[1]
    return token

def decode(auth_header):
    token = get_token_auth_header(auth_header)
    jsonurl = urlopen("https://"+AUTH0_DOMAIN+"/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())
    try:
        unverified_header = jwt.get_unverified_header(token)
    except jwt.JWTError:
        raise AuthError({"code": "invalid_header",
                        "description":
                            "Invalid header. "
                            "Use an RS256 signed JWT Access Token"}, 401)
    if unverified_header["alg"] == "HS256":
        raise AuthError({"code": "invalid_header",
                        "description":
                            "Invalid header. "
                            "Use an RS256 signed JWT Access Token"}, 401)
    rsa_key = {}
    for key in jwks["keys"]:
        if key["kid"] == unverified_header["kid"]:
            rsa_key = {
                "kty": key["kty"],
                "kid": key["kid"],
                "use": key["use"],
                "n": key["n"],
                "e": key["e"]
            }
    if rsa_key:
        try:
            payload = jwt.decode(
                token,
                rsa_key,
                algorithms=ALGORITHMS,
                audience=API_IDENTIFIER,
                issuer="https://"+AUTH0_DOMAIN+"/"
            )
        except jwt.ExpiredSignatureError:
            raise AuthError({"code": "token_expired",
                            "description": "token is expired"}, 401)
        except jwt.JWTClaimsError:
            raise AuthError({"code": "invalid_claims",
                            "description":
                                "incorrect claims,"
                                " please check the audience and issuer"}, 401)
        except Exception:
            raise AuthError({"code": "invalid_header",
                            "description":
                                "Unable to parse authentication"
                                " token."}, 401)

        print(payload)

decode('Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkZ6TGxpb3hRc1hta3hxVFQyc0VudSJ9.eyJpc3MiOiJodHRwczovL21haGRpLXZhbm5hLmF1LmF1dGgwLmNvbS8iLCJzdWIiOiJmZmxSQzEySWY2Q0RpZXE5TGIxd29MY0VOV0JBeFo0ckBjbGllbnRzIiwiYXVkIjoiaHR0cHM6Ly9tYWhkaS12YW5uYS5hdS5hdXRoMC5jb20vYXBpL3YyLyIsImlhdCI6MTYwMzg0Nzk1NSwiZXhwIjoxNjAzOTM0MzU1LCJhenAiOiJmZmxSQzEySWY2Q0RpZXE5TGIxd29MY0VOV0JBeFo0ciIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.Kz5S4zJhFH_lrHk0BgE8BfgpvfOgIMsOmR0WKAGriDE2l4iNU-3XOYIg6i0dZBxowdfYljwpe0DCWeyAlPQMHFNqqrgPj4U0RJwYEgjIsn1Xbk6-Y33TbCGsHoYwHu5aL9fowGkwQM1emSoFdnSw6CkQ_OeXJ14w01dqIuBtnsmu8vK2Khb1e1RaLFR4RLUijGROJfIZtFbp3IIAue7cG84uOzFWhhduNjLS9j4iijc9Ko7RFGDdwD7YXJ_o7A8fLU3XIwMLMcVtY7By6r3h1JxKk1HmBsiXL0p2CeZxUkazBCwujSzOuKyfbM1BdvxFApzB-AF8pAMMu2dOAJLQAA')

Great. Glad you were able to resolve this.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.