1

我正在尝试使用公钥解码 Gravitee JWT 令牌。我已经测试了 PyJWT、authlib、python-jose 和 jwcrypto 库,并查看了此页面上的很多帖子,但我在所有这些帖子中都遇到了相同的错误,我无法解决问题。

错误:

('无法反序列化密钥数据。数据可能格式不正确,可能使用不受支持的算法加密,或者可能是不受支持的密钥类型(例如具有显式参数的 EC 曲线)。', [_OpenSSLErrorWithText(code= 151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])

首先,我按照 Gravitee 的说明获得了公钥:

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

https://jwt.io关于我的令牌的一些信息:

HEADER:ALGORITHM & TOKEN TYPE

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

Python 包版本:

PyJWT==2.3.0(也用 2.1.0 测试过)

cryptography==36.0.0(一些帖子建议是必需的)

我的代码:

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

我还测试了对密钥进行编码key.encode()key.encode('ascii')或者用“BEGIN RSA PUBLIC KEY”而不是“BEGIN PUBLIC KEY”组合密钥,任何东西都对我有用。我总是有同样的错误。

4

1 回答 1

1

根据库的不同,您通常需要 JWK 格式的密钥,如以下链接所示: https ://demo.identityserver.io/.well-known/openid-configuration/jwks

这种JSON Web Key (JWK) 格式是在您处理令牌时表示键的标准,也许您的库也希望它采用这种格式?

于 2021-12-02T10:28:12.947 回答