【问题标题】:Could not deserialize key data on decoding JWT python无法反序列化解码 JWT python 的关键数据
【发布时间】:2019-04-19 15:22:36
【问题描述】:

我正在使用pyjwt 库来解码 JWT 令牌。解码时出现此错误。代码在文档中给出。

import jwt

encoded_jwt='''eyJ0eXAiOiJKV1QiLCJhbG......'''
secret=b''''-----BEGIN PUBLIC KEY-----
MIIFRjCCBC6gAwIBAgIQCIdSGhpikQCjOIY154XoqzANBgkqhkiG9w0BAQsFADBN
......
-----END PUBLIC KEY-----'''

print(jwt.decode(encoded_jwt, secret , algorithms=['RS256']))

raise ValueError("Could not deserialize key data.") ValueError: could 不反序列化关键数据。

请你帮我解决它,因为当我在JWT 网站上使用它时它正在工作。

这是完整的错误日志..

Traceback(最近一次调用最后一次):文件 “/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/algorithms.py”, 第 205 行,在 prepare_key 中 key = load_pem_private_key(key, password=None, backend=default_backend()) 文件 “/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/primitives/serialization.py”, 第 20 行,在 load_pem_private_key 中 返回 backend.load_pem_private_key(数据,密码)文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py”, 第 1014 行,在 load_pem_private_key 中 密码,文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py”, 第 1233 行,在 _load_key self._handle_key_loading_error() 文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py”, 第 1291 行,在 _handle_key_loading_error raise ValueError("无法反序列化关键数据。") ValueError: 无法反序列化关键数据。

在处理上述异常的过程中,又发生了一个异常:

Traceback(最近一次调用最后一次):文件 “/home/sathiyakugan/PycharmProjects/JWTsample/sample.py”,第 45 行,在 打印(jwt.decode(encoded_jwt,秘密,算法=['RS256']))文件 "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/api_jwt.py", 第 93 行,在解码中 jwt,键=键,算法=算法,选项=选项,**kwargs 文件 "/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/api_jws.py", 第 157 行,在解码中 密钥,算法)文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/api_jws.py”, 第 221 行,在 _verify_signature key = alg_obj.prepare_key(key) 文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/jwt/algorithms.py”, 第 207 行,在 prepare_key 中 key = load_pem_public_key(key, backend=default_backend()) 文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/primitives/serialization.py”, 第 24 行,在 load_pem_public_key 返回 backend.load_pem_public_key(data) 文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py”, 第 1040 行,在 load_pem_public_key self._handle_key_loading_error() 文件“/home/sathiyakugan/PycharmProjects/Python/venv/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py”, 第 1291 行,在 _handle_key_loading_error raise ValueError("无法反序列化关键数据。") ValueError: 无法反序列化关键数据。

进程以退出代码 1 结束

【问题讨论】:

  • @stovfl 不,这是不同的问题
  • 您似乎有错字。在您的公钥中多加一个撇号,就在开头。

标签: python authentication oauth jwt encode


【解决方案1】:

你是如何编码你的 jwt 的?使用以下方法之一

使用 RS256 (RSA) 编码和解码令牌

encoded = jwt.encode({'some': 'payload'}, private_key, algorithm='RS256')
decoded = jwt.decode(encoded, public_key, algorithms='RS256')

无需验证即可读取声明集

jwt.decode(encoded, verify=False)
{u'some': u'payload'}

或者使用相同的秘密对 jwt 进行编码和解码,其中一种方法应该可以工作。就我而言,我使用了jwt.decode(token, verify=False),因为我的服务器已经为我进行了签名验证,我只需要获取声明集。

【讨论】:

  • 这对我不起作用,它在编码数据时显示ValueError: Could not deserialize key data.
  • 带公钥或不带公钥的解码方法哪个不适合你
  • 在我的情况下,问题在于编码,我们可以使用上述流程进行编码,但我们需要正确加载私钥,我在:github.com/jpadilla/pyjwt/issues/320 上找到了这个,之后我就可以进行编码了并解码。
【解决方案2】:

pyjwt 库中存在一些问题。并且您必须从证书中获取公钥。

我用openssl x509 -pubkey -noout -in cert.pem > pubkey.pem

然后我可以通过公钥轻松地使用 authlib 库对其进行解码。

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)

【讨论】:

    【解决方案3】:

    使用authlib 库,我从未设法用pyjwt 解码keycloak 令牌。 你需要一个public_key,我想你有它。

    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
        #...
    

    专业提示:您可以在某个端点从您的身份验证服务器(在我的情况下为 Keycloak)轻松获取公钥:

    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']
    

    【讨论】:

    • “我从来没有设法用 pyjwt 解码 keycloak 令牌”我在这里聚会迟到了,但使用 pyjwt 验证来自 Keycloak 的 JWT 时遇到了类似的问题。我终于意识到这是因为 pyjwt 只需要 PUBLIC-KEY 值(不是完整的 PEM 证书)。我通过将 Keycloak 提供的 x509 证书转换为 PEM 文件(通过将其包装在“-----BEGIN/END CERTIFICATE-----”行中)并使用以下 openssl 命令提取公钥值:openssl x509 -pubkey -noout -in certificate.pem。然后生成的公钥输出与 pyjwt 一起使用。
    【解决方案4】:

    将 RSA 密钥与 OpenSSL 一起使用是个好主意:

    openssl genrsa -out jwt-key 4096
    openssl rsa -in jwt-key -pubout > jwt-key.pub
    

    参考:link

    【讨论】:

    • 我遇到了类似的问题,这就是我的问题的解决方案。谢谢,并推荐答案(虽然我没有检查其他人)
    【解决方案5】:

    如果您收到此错误,请仔细检查您的公钥是否完全正确,新行很重要。

    key = '''-----BEGIN PUBLIC KEY-----
    <main key here>
    -----END PUBLIC KEY-----'''
    

    【讨论】:

    • 这真的很有帮助,应该是公认的答案。
    【解决方案6】:

    对我来说,导致此问题的键(愚蠢的 IDE)中有空格,请确保您不是这种情况

    【讨论】:

      【解决方案7】:

      MacOS Catalina 10.15.4 Python 2.7.16。

      这解决了我的问题

      pip install cryptography==2.3
      

      【讨论】:

        猜你喜欢
        • 2023-02-18
        • 2019-06-16
        • 2018-09-29
        • 2019-10-08
        • 1970-01-01
        • 2021-02-17
        • 1970-01-01
        • 1970-01-01
        • 2019-11-27
        相关资源
        最近更新 更多