【问题标题】:ValueError: Could not deserialize key data during jwt encodingValueError:在 jwt 编码期间无法反序列化密钥数据
【发布时间】:2019-10-08 14:35:29
【问题描述】:

我正在尝试使用 jwt 生成令牌,并且正在传递有效负载、secret_key 和算法(“RS256”)。下面是部分代码

secret_key = AppConfig.JWT_SECRET_KEY
public_key = AppConfig.JWT_PUBLIC_KEY
payload = {'UserInfo': user_one.to_dict()}
payload['UserInfo']['picture'] = 'https://someimage.url'
payload.__setitem__('exp', exp) if exp is not None else ''
token = jwt.encode(payload, secret_key, algorithm='RS256').decode(CHARSET)

我收到了这个错误

  File "/root/.pyenv/versions/3.6.5/lib/python3.6/code.py", line 91, in runcode
    exec(code, self.locals)
  File "<console>", line 1, in <module>
  File "/activo-api/tests/helpers/generate_token.py", line 30, in generate_token
    token = jwt.encode(payload, secret_key, algorithm='RS256').decode(CHARSET)
  File "/root/.local/share/virtualenvs/activo-api-lpKgDXk8/lib/python3.6/site-packages/jwt/api_jwt.py", line 65, in encode
    json_payload, key, algorithm, headers, json_encoder
  File "/root/.local/share/virtualenvs/activo-api-lpKgDXk8/lib/python3.6/site-packages/jwt/api_jws.py", line 113, in encode
    key = alg_obj.prepare_key(key)
  File "/root/.local/share/virtualenvs/activo-api-lpKgDXk8/lib/python3.6/site-packages/jwt/algorithms.py", line 207, in prepare_key
    key = load_pem_public_key(key, backend=default_backend())
  File "/root/.local/share/virtualenvs/activo-api-lpKgDXk8/lib/python3.6/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 20, in load_pem_public_key
    return backend.load_pem_public_key(data)
  File "/root/.local/share/virtualenvs/activo-api-lpKgDXk8/lib/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1071, in load_pem_public_key
    self._handle_key_loading_error()
  File "/root/.local/share/virtualenvs/activo-api-lpKgDXk8/lib/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1329, in _handle_key_loading_error
    raise ValueError("Could not deserialize key data.")
ValueError: Could not deserialize key data.

当我使用HS256 algorithm 时,会生成一个令牌,但是当我使用RS256 algorithm 时,我会收到上述错误。我已经尝试了几乎所有在线提供的解决方案,但我仍然遇到同样的错误。

我的密钥格式如下:

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA3Tz2mr7SZiAMfQyuvBjM9Oi
RK+Lh9x5eJPo5CAZ3/ANBE0sTK0ZsDGMak2m1g7
wnLe4nOb7/eEJbDPkk05ShhBrJGBKKxb8n104o/
...........
5A13wiLitEO7nco2WfyYkQzaxCw0AwzlkVHiIyC
DtkpjGHQzPF6vOe907y5NQLvVFGXUq/FIJZxB8d==
-----END RSA PRIVATE KEY-----

预期的输出应该是一个令牌

【问题讨论】:

  • 您的公钥文件似乎有问题。
  • 这不是真正的关键。我只是提供格式。让我提供一个更好的例子

标签: python jwt python-cryptography


【解决方案1】:

第一:

pip install cryptography

您必须使用 OpenSSL 创建 RSA 密钥:

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

参考:enter link description here

【讨论】:

    【解决方案2】:

    所以,字符串 PEM 密钥对我不起作用。

    所以我决定将它们序列化。有几种常见的方案可将非对称私钥和公钥序列化为字节。它们通常支持加密私钥和其他密钥元数据。解决步骤如下:

    使用jwt.encode()生成令牌时

    1. 导入以下依赖项

      • from cryptography.hazmat.backends import default_backend
      • from cryptography.hazmat.primitives import serialization
    2. 编码时不传递PEM私钥的字符串格式, 序列化如下

      secret_key = serialization.load_pem_private_key(
          secret_key_string.encode(), password=None, backend=default_backend())
      payload = {'UserInfo': {"name":"name", "email":"user@email.com"}
      payload.__setitem__('exp', exp) if exp is not None else ''
      token = jwt.encode(payload, secret_key, algorithm='RS256').decode(CHARSET)```
      

    通常,jwt.encode() 方法将secret(字符串)作为其参数之一。在上面的例子中,我们将serialized object 作为secret 传递

    使用 jwt.decode() 解码令牌时

    将公钥从 PEM 编码数据反序列化为受支持的非对称公钥类型之一。为了成功解码令牌,请按照以下步骤操作

    1. 导入以下依赖项
      • from cryptography.hazmat.backends import default_backend
      • from cryptography.hazmat.primitives import serialization
    2. 使用utf-8对PEM公钥进行编码,并将ifload_pem_public_key()方法作为参数传递,以便将其序列化如下

      public_key = AppConfig.JWT_PUBLIC_KEY public_key_obj = serialization.load_pem_public_key( public_key.encode(), backend=default_backend())

    3. 通过将序列化的公钥对象传递给jwt.decode()方法来解码令牌,如下所示

      decoded_token = jwt.decode(token,public_key_obj, algorithms=['RS256'], options={ 'verify_signature': True, 'verify_exp': True })

    您可以找到有关序列化 PEM 公钥和 PEM 私钥的更多信息Here

    【讨论】:

      猜你喜欢
      • 2020-11-26
      • 2021-12-27
      • 2019-04-19
      • 2023-02-18
      • 2021-04-05
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多