【Python】itsdangerous在Django中加密解密的使用

籍辰沛
2023-12-01

起因

我们知道HTTP是不安全的,所以在Django中,为了加密传输的数据(可以是密码、邮件、URL,类型可以是字符串、JSON、列表等等),可以使用itsdangerous进行加密和解密数据。

如加密一个URL的参数。

使用itsdangerous可以很方便的让我们进行可逆的加密解密。

安装

pip install itsdangerous

JSON Web Signature (JWS)

文档:https://itsdangerous.palletsprojects.com/en/1.1.x/jws/

1. 有过期时间的签名——TimedJSONWebSignatureSerializer

未过期时可以解密

In[1]:from itsdangerous import TimedJSONWebSignatureSerializer # 导入时间JSON签名序列化包
In[2]:serializer1 = TimedJSONWebSignatureSerializer(secret_key='secret-key', expires_in=3600)    # 密钥和过期时间
In[3]:info = {'content':9527}   # JSON,也可以是list类型、字符串类型
In[4]:res = serializer1.dumps(info).decode() # 加密
In[5]:res
Out[5]: 'eyJhbGciOiJIUzUxMiIsImlhdCI6MTU5MDE1MDQ0MywiZXhwIjoxNTkwMTU0MDQzfQ.eyJjb250ZW50Ijo5NTI3fQ.SyIcvnG8yOHPA1teNhK3htc50WgWHJxA9-4-6DS0Zlk4Q4zWV5GKUAv2axmhio4ry0YdQls5Lc1eoIZDR8Cvdw'
In[6]:serializer1.loads(res)    # 解密
Out[6]: {'content': 9527}

过期后解密会报错

In[7]:serializer1 = TimedJSONWebSignatureSerializer(secret_key='secret-key', expires_in=1) # 1秒后过期
In[8]:res = serializer1.dumps(info)
In[9]:serializer1.loads(res)
Traceback (most recent call last):
  File "D:\Python3.7.5\lib\site-packages\IPython\core\interactiveshell.py", line 3319, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-26-9a4867386e07>", line 1, in <module>
    serializer1.loads(res)
  File "D:\Python3.7.5\lib\site-packages\itsdangerous\jws.py", line 205, in loads
    date_signed=self.get_issue_date(header),
itsdangerous.exc.SignatureExpired: Signature expired

2. 可以加salt的签名——JSONWebSignatureSerializer

什么叫salt呢?salt盐,其实就是由服务器随机生成的一个字符串,但是要保证长度足够长,并且是真正随机生成的。然后把它和密码字符串相连接(任意规则连接)生成散列值。当两个用户使用了同一个密码时,由于随机生成的salt值不同,对应的散列值也将是不同的。这样一来,很大程度上减少了密码特征,攻击者也就很难利用自己手中的密码特征库进行破解。

——《图解HTTP》

提醒:

  1. HTTP传输时,为了使数据更安全,可以加salt(随机字符串)再散列。
  2. isdangerous中,盐其实就是一个附加字符串,可以区别用途:
In[1]:from itsdangerous.url_safe import URLSafeSerializer
In[2]:s1 = URLSafeSerializer("secret-key", salt="activate")   # 激活账户
In[3]:s1.dumps(42)
Out[3]:'NDI.MHQqszw6Wc81wOBQszCrEE_RlzY'
In[4]:s2 = URLSafeSerializer("secret-key", salt="upgrade")    # 升级账户
In[5]:s2.dumps(42)
Out[5]:'NDI.c0MpsD6gzpilOAeUPra3NShPXsE'

实际使用

In[1]:from itsdangerous import JSONWebSignatureSerializer
In[2]:s = JSONWebSignatureSerializer("secret-key", salt="Jc$@85idhhg1^&")
In[3]:res = s.dumps({"x": 42})
In[4]:res
Out[4]:'eyJhbGciOiJIUzI1NiJ9.eyJ4Ijo0Mn0.ZdTn1YyGz9Yx5B5wNpWRL221G1WpVE5fPCPKNuc6UAo'
In[5]:s.loads(res)
Out[5]: {'x': 42}
In[6]:s.dumps('1233145').decode()
Out[6]: 'eyJhbGciOiJIUzUxMiJ9.IjEyMzMxNDUi.3bDpp2x73YsS4w6p_5Dg_4sgO49iJyWCjZsiFIdLczjawsxVVH99Rszkc9qixMfD1BxIxJmtQRcUJrimQrCKyg'
In[7]:s.loads('eyJhbGciOiJIUzUxMiJ9.IjEyMzMxNDUi.3bDpp2x73YsS4w6p_5Dg_4sgO49iJyWCjZsiFIdLczjawsxVVH99Rszkc9qixMfD1BxIxJmtQRcUJrimQrCKyg')
Out[38]: '1233145'

还有其他的:

 类似资料: