itsdangerous模块

使用场景:

  • 在取消订阅时,可以在URL里序列化并且签名一个用户的ID或在任何的激活账户的链接或类似的情形下使用。这种情况下不需要生成一个一次性的token并把它们存到数据库中。
  • 被签名的对象可以被存入cookie中或其他不可信来源,这意味着不需要在服务端保存session,这样可以降低数据库读取的次数。
  • 通常签名后的信息可以安全地往返与服务端与客户端之间,这个特性可以用于将服务端的状态传递到客户端再传递回来。

签名接口:

最基本的接口是签名接口。Signer类可以用来将一个签名附加到指定的字符串上

注:sign()方法需要传bytes类型数据,不然会报错

# 发送方和接收方拥有相同的密钥--"secret-key",发送方使用密钥对发送内容进行签名,接收方使用相同的密钥对接收到的内容进行验证,看是否是发送方发送的内容
from itsdangerous import Signer
s = Signer('secret-key')  # 参数传自己的密钥
s.sign(b'1234566322345663')  #获取签名,得到的结果是签名加在传入的字符串尾部,以.分隔  # b'1234566322345663.DWnk3y4kwfTAiTJ1kNZ1mNSabOU'
# 验证字符串,使用unsign()方法:
s.unsign('1234566322345663.DWnk3y4kwfTAiTJ1kNZ1mNSabOU')
# 如果被签名的是一个unicode字符串,那么它将隐式地被转换成utf-8。然而,在反签名时,你没法知道它原来是unicode还是字节串。
# 如果反签名验证失败了,会主动抛出异常 '''itsdangerous.exc.BadSignature: Signature b'DWnk3y4kwfTAiTJ1kNZ1mNSabOUsd' does not match'''

使用时间戳签名:

如果想要可以过期的签名,可以使用TimestampSigner类,它会加入时间戳信息并签名。在反签名时,可以验证时间戳有没有过期

from itsdangerous import TimestampSigner
s1 = TimestampSigner('secret-key')
# string = s1.sign('foo')  # b'foo.XSmkVg.A6ZSwzOnVlVaNCkk12Fqo4gFRQk'
# 得到签名结果后,将上面签名的代码先注释掉,然后再反签名
s1.unsign('foo.XSmkVg.A6ZSwzOnVlVaNCkk12Fqo4gFRQk', max_age=5)
# 这里设置的5s过期,那么只要反签名的时间超过5s都是过期,下面是异常信息
'''itsdangerous.exc.SignatureExpired: Signature age 34 > 5 seconds'''

序列化:

# 因为字符串难以处理,本模块也提供了一个与json或pickle类似的序列化接口。(它内部默认使用simplejson,但是可以通过子类进行修改)
from itsdangerous import Serializer
# 签名 s2
= Serializer('secret-key')
s2.dumps([1, 2, 3, 4]) # [1, 2, 3, 4].r7R9RhGgDPvvWl3iNzLuIIfELmo # 反签名,加载数据 s2.loads('[1, 2, 3, 4].r7R9RhGgDPvvWl3iNzLuIIfELmo')

带时间戳的序列化:

from itsdangerous import TimedSerializer
# 签名 s
=TimedSerializer('secret-key') s.dumps([1,2,3,4]) # '[1, 2, 3, 4].DI7WHQ.yVOjwQWau5mVRGuVkoqa7654VXc' s.loads('[1, 2, 3, 4].DI7WHQ.yVOjwQWau5mVRGuVkoqa7654VXc') # [1, 2, 3, 4] s.loads('[1, 2, 3, 4].DI7WHQ.yVOjwQWau5mVRGuVkoqa7654VXc',max_age=10) # [1, 2, 3, 4]

URL安全序列化:

如果能够向只有字符受限的环境中传递可信的字符串的话,将十分有用。itsdangerous也提供了一个URL安全序列化工具

from itsdangerous import URLSafeSerializer
# 签名
s = URLSafeSerializer('secret-key')
s.dumps([1, 2, 3, 4])  # 'WzEsMiwzLDRd.wSPHqC0gR7VUqivlSukJ0IeTDgo'
# 反签名
s.loads('WzEsMiwzLDRd.wSPHqC0gR7VUqivlSukJ0IeTDgo')  # [1, 2, 3, 4]

JSON Web 签名:

json web签名工作方式与原有的URL安全序列化差不多,但是会根据当前JSON Web签名

from itsdangerous import JSONWebSignatureSerializer
# 签名
s = JSONWebSignatureSerializer('secret-key')
s.dumps({'x': 42}) 
 # 'eyJhbGciOiJIUzI1NiJ9.eyJ4Ijo0Mn0.ZdTn1YyGz9Yx5B5wNpWRL221G1WpVE5fPCPKNuc6UAo'

s.dumps(0, header_fields={'v': 1})  # 'eyJhbGciOiJIUzI1NiIsInYiOjF9.MA.wT-RZI9YU06R919VBdAfTLn82_iIQD70J_j-3F4z_aM'
# 反签名
s.loads('eyJhbGciOiJIUzI1NiIsInYiOjF9.MA.wT-RZI9YU06R919VBdAfTLn82_iIQD70J_j-3F4z_aM', return_header=True)  # (0, {u'alg': u'HS256', u'v': 1})
根据当前JSON Web签名(JWS)草案(10)[draft-ietf-jose-json-web-signature] 来生成 header。签名时可以传入header_fields 参数,反签名传入return_header=True参数来得到header

带有时间戳的JSON WEB 签名:

from itsdangerous import TimedJSONWebSignatureSerializer
s = TimedJSONWebSignatureSerializer('secret_key',10)  # 设置有效期为10s
# 签名
s.dumps({'id':1})
# 反签名
s.loads('xxxxxxxxxxxx')
# 如果超过设置的有效期则反签名时抛出SignatureExpired签名过期的错误

加盐加密:

 itsdangerous 中所有的类都接收一个盐的参数salt,密码学中的盐是一个和被签名的字符串存储在一起的东西,作用是防止彩虹表查找。这种盐是可以公开的。你可以将它视为一个命名空间,泄露也没事,只要密钥没泄露,攻击者就没办法破解。

使用举例:在对同一个用户的激活账户和升级vip时加入不同的盐值,即可得到不同的签名,且使用相同盐的序列化器才能成功反签名。

原文地址:https://www.cnblogs.com/eat-w/p/12055245.html