FastAPI开发基础之python-jose

简介

python-jose是Python版本的JOSE实现。“JOSE”意思是JavaScript对象签名和加密(JavaScript Object Signing and Encryption)技术,这个库中包含了如下4个子库:

  • JSON Web签名(JWS)
  • JSON Web加密(JWE)
  • JSON Web密钥(JWK)
  • JSON Web算法(JWA)
    上述各子库,可以共同用于使用各种算法对内容进行加密和/或签名。虽然所有这些库显得格外庞大,甚至可能会令一些人望而生畏,但预计大多数应用程序将只使用其中的小部分算法即可满足业务需求。
    【注意】这个Python版本的JOSE实现与依赖于PyCrypto库的Google App Engine完全兼容。

    安装

    pip install python-jose[cryptography]

    后端加密类型

    从3.1.0版本开始,python实现了四种不同的后端加密类型。因此,安装python-jose时,应当确定一下选择安装哪一种类型的后端。如果不选择哪一种类型,则默认安装native-python后端。除非另有说明;否则,所有后端类型都支持所有操作。
    【注意】由于安装工具的复杂性,总会安装native-python这种后端类型——即使你安装时选择了不同的后端也是如此。但是,在部署项目时我们建议你删除其中不必要的依赖项。

    1. cryptography

    此后端对所有加密操作都使用pyca/cryptography。这也是推荐的后端类型,如果存在任何其他后端类型的话,这种类型是推荐优先于所有其他后端类型使用的。
    安装命令:pip install python-jose[cryptography]
    选择此类型时,未使用的依赖项有:

  • rsa
  • ecdsa
  • pyasn1

    2. pycryptodome

    这种后端使用pycryptome进行所有加密操作。
    安装命令:pip install python-jose[pycryptodome]
    选择此类型时,未使用的依赖项有:

  • rsa

    3. native-python

    此后端使用python-rsa和python-ecdsa执行所有加密操作。此后端类型将始终安装,但如果安装了任何其他后端,则将优先安装使用其他后端。
    安装命令:pip install python-jose
    【注意】native-python后端类型无法处理证书问题。

    4. pycrypto

    此后端使用pycrypto执行所有加密操作。
    安装命令:pip install python-jose[pycrypto]
    选择此类型时,未使用的依赖项有:

  • rsa
    【警告】pycrypto项目自2013年以来一直未得到维护。此后端仅出于与旧版兼容性的目的而维护。除非不能使用其他任何后端,否则不要使用此后端。

    举例

    例1:JSON Web令牌(JWT)编解码

    from jose import jwt
    token = jwt.encode({'key': 'value'}, 'secret', algorithm='HS256')
    u'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ2YWx1ZSJ9.FG-8UppwHaFp1LgRYQQeS6EDQF7_6-bMFegNucHjmWg'

jwt.decode(token, 'secret', algorithms=['HS256'])
{u'key': u'value'}

例2:使用JWS签名令牌和验证令牌签名

签名令牌:
from jose import jws
signed = jws.sign({'a': 'b'}, 'secret', algorithm='HS256')
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8'
验证令牌签名:
jws.verify(signed, 'secret', algorithms=['HS256'])
{'a': 'b'}

例3:使用JWK验证令牌签名

from jose import jwk
from jose.utils import base64url_decode

token = "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0"
hmac_key = {
"kty": "oct",
"kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037",
"use": "sig",
"alg": "HS256",
"k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg"
}

key = jwk.construct(hmac_key)

message, encoded_sig = token.rsplit('.', 1)
decoded_sig = base64url_decode(encoded_sig)
key.verify(message, decoded_sig)
【注意】python-jose需要使用公钥,而不是X.509证书。如果您有一个X.509证书,您想将其转换为python-jose可以使用的公钥,那么可以使用openssl来实现,方式如下:
openssl x509 -pubkey -noout < cert.pem

例4:使用JWE加密

JSON Web加密(JWE)用于加密“有效负载”(真正要加密的内容),并将其表示为紧凑的URL安全字符串。
加密“有效负载”代码:
from jose import jwe
jwe.encrypt('Hello, World!', 'asecret128bitkey', algorithm='dir', encryption='A128GCM')
'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIn0..McILMB3dYsNJSuhcDzQshA.OfX9H_mcUpHDeRM4IA.CcnTWqaqxNsjT4eCaUABSg'
解密“有效负载”代码:
from jose import jwe
jwe.decrypt('eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIn0..McILMB3dYsNJSuhcDzQshA.OfX9H_mcUpHDeRM4IA.CcnTWqaqxNsjT4eCaUABSg', 'asecret128bitkey')
'Hello, World!'

参考

https://python-jose.readthedocs.io/en/latest/
https://github.com/mpdavis/python-jose

猜你喜欢

转载自blog.51cto.com/zhuxianzhong/2572015