Python ValueError:在jwt编码期间无法反序列化密钥数据

Python ValueError:在jwt编码期间无法反序列化密钥数据,python,jwt,python-cryptography,Python,Jwt,Python Cryptography,我试图使用jwt生成一个令牌,并传递有效负载、密钥和算法(“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',

我试图使用jwt生成一个令牌,并传递有效负载、密钥和算法(“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.

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

,因此字符串PEM密钥对我不起作用

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

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

  • 导入以下依赖项

    • 从cryptography.hazmat.backends导入默认\u backend
    • 从cryptography.hazmat.primitives导入序列化
  • 编码时不传递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
    (字符串)作为其参数之一。在上面的例子中,我们将
    序列化对象
    作为
    秘密

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

    将PEM编码数据中的公钥反序列化为支持的非对称公钥类型之一。要成功解码令牌,请执行以下步骤

  • 导入以下依赖项
    • 从cryptography.hazmat.backends导入默认\u backend
    • 从cryptography.hazmat.primitives导入序列化
  • 使用
    utf-8
    对PEM公钥进行编码,并将if
    load\u PEM\u public\u key()
    方法作为参数传递,以便按如下方式序列化

    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)```
    
    public\u key=AppConfig.JWT\u public\u key
    public\u key\u obj=serialization.load\u pem\u public\u key(
    public_key.encode(),backend=default_backend())

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

    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)```
    
    decoded_token=jwt.decode(token,public_key_obj,
    算法=['RS256'],
    选择权={
    “验证签名”:True,
    'verify_exp':True
    })

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

    第一:

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

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

    参考资料:

    您的公钥文件似乎有错误。这不是实际的密钥。我只是提供格式。让我举一个更好的例子