1

I'm trying to decode a Gravitee JWT Token using public key. I tested already PyJWT, authlib, python-jose and jwcrypto libraries and review a lot of posts on this page but I get the same error in all of them and I could not fix the problem.

Error:

('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])

Firts of all I get the public key following Gravitee instructions:

https://docs.gravitee.io/am/current/am_userguide_create_certificate.html

Some info from https://jwt.io about my token:

HEADER:ALGORITHM & TOKEN TYPE

{
  "kid": "default",
  "alg": "RS256"
}

Python packeges versions:

PyJWT==2.3.0 (also tested with 2.1.0)

cryptography==36.0.0 (some posts suggests is required)

My code:

from rest_framework import permissions
from rest_framework.exceptions import APIException
from django.conf import settings
import jwt


class TokenNotValid(APIException):
    status_code = 403
    default_detail = "Invalid or absent JWT token field."


class NoAuthHeader(APIException):
    status_code = 403
    default_detail = "Absent 'Authorization' header."


class ValidJWTPermission(permissions.BasePermission):
    """
    Global permission check for JWT token.
    """

    def _get_pubkey(self):
        key = """-----BEGIN PUBLIC KEY-----\n""" + settings.GRAVITEE_PUBLIC_KEY + """\n-----END PUBLIC KEY-----"""
        return key

    def has_permission(self, request, view):

        auth_header = request.META.get('HTTP_AUTHORIZATION')
        # print("Received header:")
        # print(auth_header)
        if auth_header is None:
            raise NoAuthHeader

        try:
            token = auth_header.split()[1]
            # print("Encoded Token:")
            # print(token)
            public_key = self._get_pubkey()
            print(public_key)

            claims = jwt.decode(token, key=public_key, algorithms=['RS256'])
            claims.validate()
        except Exception as e:
            print(e)
            raise TokenNotValid

        # print("Decoded token:")
        # print(dec_token)

        return True

I tested also encoding the key like key.encode() and key.encode('ascii') or composing the key with "BEGIN RSA PUBLIC KEY" instead of "BEGIN PUBLIC KEY" and anything works for me. Always I have the same error.

Ganuher
  • 11
  • 3

1 Answers1

1

Depending on the library, you often wants the key in JWK format as shown in this link: https://demo.identityserver.io/.well-known/openid-configuration/jwks

This JSON Web Key (JWK) format is a standard for representing keys when you deal with tokens and perhaps you library wants it in that format too?

Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40
  • Thanks for your response. Library wants PEM and doesn't support JWK format, I had tried a lot of possibilities with key format but any of them works. – Ganuher Dec 02 '21 at 13:11
  • have you verified using openssl that you can actually read the key and it is valid? like using "openssl rsa -text -noout -pubin -in rsa-public-key.pem" – Tore Nestenius Dec 06 '21 at 10:23