python 密码学 模块_python学习-itsdangerous模块-黑马程序员技术交流社区
博客鏈接地址:http://www.zhuyannan.top/itsdangerous-加密你的數(shù)據(jù)/
如果你想向不可信的環(huán)境發(fā)送數(shù)據(jù),但又擔心數(shù)據(jù)被別人利用,就可以使用 itsdangerous來加密簽名你的數(shù)據(jù)。
接收者可以破譯內(nèi)容,來看看你的包裹里有什么,但他們沒辦法修改你的內(nèi)容,除非他們也有你的密鑰。itsdangerous內(nèi)部默認使用了HMAC和SHA1來簽名,基于 Django 簽名模塊。它也支持JSON Web 簽名 (JWS)。這個庫采用BSD協(xié)議,由Armin Ronacher編寫,而大部分設(shè)計與實現(xiàn)的版權(quán)歸Simon Willison和其他的把這個庫變?yōu)楝F(xiàn)實的Django愛好者們。0.安裝1pip install itsdangerous1.簽名接口
Signer 類可以用來將一個簽名附加到指定的字符串上,這個是最基本的簽名接口1
2
3
4
5
6In [1]: from itsdangerous import Signer
In [2]: s = Signer('secret_key')
In [3]: s.sign(b'hello')
Out[3]: b'hello.v8Y625GovH2FcEWU_j5w1klqs0I'
可以看出,簽名被加到字符串 hello 的尾部,并且以 . 隔開。(注意:這里的 sign() 需要傳bytes類型數(shù)據(jù),不然會報錯)
如果要反簽名,使用 unsign() 方法:1
2In [4]: s.unsign('hello.v8Y625GovH2FcEWU_j5w1klqs0I') # 這里也可以傳bytes數(shù)據(jù)
Out[4]: b'hello'
如果反簽名失敗,會得到 BadSignature 的異常。2.使用時間戳簽名
如果想要簽名可以過期,可以使用 TimeStampSigner 類,它會加入時間戳信息并簽名。1
2
3
4
5
6
7
8In [6]: from itsdangerous import TimestampSigner
In [7]: s = TimestampSigner('secret_key')
In [8]: string = s.sign('hello')
In [9]: string
Out[9]: b'hello.DmZg2g.idiRG3HJdMzUNN-di8LXHKiEW5s'
反簽名時,可以驗證碼時間戳是否過期1
2
3
4
5
6
7In [10]: s.unsign(string) # 沒有輸入有效期,是可以直接反簽名
Out[10]: b'hello'
In [11]: s.unsign(string,max_age=5)??# 輸入有效期 5s
SignatureExpired? ?? ?? ?Traceback (most recent call last)
.....
SignatureExpired: Signature age 48 > 5 seconds
可以看出在反簽名時,我輸入了5s的有效期,但是進行反簽名時,已經(jīng)過了48s,所以報錯了,提示 Signature age 48 > 5 seconds3.序列化
對于非字符串的數(shù)據(jù),Signer 類處理不了,這個模塊也提供了類似 json 的序列化接口 —-> Serializer 類
簽名使用 Serializer 對象的 dumps() ,反簽名使用 loads()1
2
3
4
5
6
7
8
9In [13]: from itsdangerous import Serializer
In [14]: s = Serializer('secret_key')
In [15]: s.dumps({'name':'zhangsan','age':18})
Out[15]: '{"name": "zhangsan", "age": 18}.SQd5BPTqTZQ4vLOEN7PKBYWMsas'
In [16]: s.loads('{"name": "zhangsan", "age": 18}.SQd5BPTqTZQ4vLOEN7PKBYWMsas')
Out[16]: {'name': 'zhangsan', 'age': 18}4.URL安全序列化
如果要想向不可信的環(huán)境傳遞數(shù)據(jù),可以使用URL安全序列化工具1
2
3
4
5
6
7
8
9In [23]: from itsdangerous import URLSafeSerializer
In [25]: s = URLSafeSerializer('secret_key')
In [26]: s.dumps([1,2,3])
Out[26]: 'WzEsMiwzXQ.1JvL0-RdbHYdszhKCATOTdQEZl0'
In [27]: s.loads('WzEsMiwzXQ.1JvL0-RdbHYdszhKCATOTdQEZl0')
Out[27]: [1, 2, 3]
同樣也有添加時間戳的URL安全序列化類 URLSafeTimedSerializer,就不舉例了5.JSON WEB 簽名
它的工作方式與URL安全序列化器差不多1
2
3
4
5
6
7
8
9
10In [29]: from itsdangerous import JSONWebSignatureSerializer
In [30]: s = JSONWebSignatureSerializer('secret_key')
In [31]: s.dumps({'name':'mike'})
Out[31]: b'eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoibWlrZSJ9.A9eujaivW63mvCSmz_6KVT6sDtLneBe3U62wCoSellY'
In [32]: s.loads('eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoibWlrZSJ9.A9eujaiv
...: W63mvCSmz_6KVT6sDtLneBe3U62wCoSellY')
Out[32]: {'name': 'mike'}
但是會根據(jù)當前 JSON Web簽名(JWS) 草案(10) [draft-ietf-jose-json-web-signature] 來生成 header。
簽名時可以傳入header_fields 參數(shù),反簽名傳入return_header=True 參數(shù)來得到 header1
2
3
4
5
6In [34]: s.dumps({'name':'mike'},header_fields={'myheader':123})
Out[34]: b'eyJteWhlYWRlciI6MTIzLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoibWlrZSJ9.mE-UAcsVsqisJj6EIOF1ocahGdRz5cbZyyySF39OREQ'
In [35]: s.loads('eyJteWhlYWRlciI6MTIzLCJhbGciOiJIUzI1NiJ9.eyJuYW1lI
...: joibWlrZSJ9.mE-UAcsVsqisJj6EIOF1ocahGdRz5cbZyyySF39OREQ',return_header=True)
Out[35]: ({'name': 'mike'}, {'myheader': 123, 'alg': 'HS256'})
加載回來的header里還包含當前使用的算法 {‘a(chǎn)lg’: ‘HS256’},itsdangerous 目前只提供HMAC SHA的派生算法以及不使用算法,不支持基于ECC的算法。6.TimedJSONWebSignatureSerializer
帶有時間戳的JSON WEB 簽名1
2
3
4
5
6
7
8
9
10
11
12
13In [42]: from itsdangerous import TimedJSONWebSignatureSerializer
In [43]: s = TimedJSONWebSignatureSerializer('secret_key',10)??# 設(shè)置有效期為 10s
In [44]: s.dumps({'id':1})
Out[44]: b'eyJhbGciOiJIUzI1NiIsImlhdCI6MTUzNTQzNTg3NSwiZXhwIjoxNTM1NDM1ODg1fQ.eyJpZCI6MX0.vZ5fDRR1-zBJk2nOH7kpdQIxvEv8dru0C3o_wuagIec'
In [45]: s.loads('eyJhbGciOiJIUzI1NiIsImlhdCI6MTUzNTQzNTg3NSwiZXhwIj
...: oxNTM1NDM1ODg1fQ.eyJpZCI6MX0.vZ5fDRR1-zBJk2nOH7kpdQIxvEv8dr
...: u0C3o_wuagIec')
Traceback (most recent call last)
.....
SignatureExpired: Signature expired
可以看出,反簽名時拋出 SignatureExpired 簽名過期的錯誤,原因是因為我設(shè)置了有效期10s,但是我執(zhí)行反簽名時,時間已經(jīng)過了 10s 的有效期。7.加鹽加密
itsdangerous 中所有的類都接收一個鹽的參數(shù),密碼學(xué)中的鹽是一個和被簽名的字符串存儲在一起的東西,作用是防止彩虹表查找。這種鹽是可以公開的。你可以將它視為一個命名空間,泄露也沒事,只要密鑰沒泄露,攻擊者就沒辦法破解。
舉個簡單的例子來演示:
假設(shè)你想簽名鏈接,一個郵箱激活鏈接,一個郵箱升級VIP的鏈接,簽名都是 user ID,那么在激活和升級時就可以復(fù)用這個可變的部分,但是可以在簽名的地方加上更多信息,使用不同的鹽來說明你的意圖。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19In [36]: s = URLSafeSerializer('scret_key',salt='verify_salt')??# 激活使用的鹽
In [37]: s.dumps(10)? ?# 假設(shè)用戶的 id=10
Out[37]: 'MTA.jz5Oj-RsTztx1o0KQhhjdEL2z9E'
In [38]: s_vip = URLSafeSerializer('secret_key',salt='vip_salt') # 升級vip使用的鹽
In [39]: s_vip.dumps(10)
Out[39]: 'MTA.j_qvVU-kNlTimdlgMty0qcy_618'
# 反簽名時,使用 salt=vip_salt 的對象去加載 salt='verify_salt' 對象,就會報簽名錯誤
In [40]: s_vip.loads(s.dumps(10))
Traceback (most recent call last)
.....
BadSignature: Signature b'jz5Oj-RsTztx1o0KQhhjdEL2z9E' does not match
# 使用相同鹽的序列化器才能成功反簽名
In [41]: s_vip.loads(s_vip.dumps(10))
Out[41]: 10
總結(jié)
以上是生活随笔為你收集整理的python 密码学 模块_python学习-itsdangerous模块-黑马程序员技术交流社区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 脆冬枣的功效与作用、禁忌和食用方法
- 下一篇: 可乐鸡翅的功效与作用、禁忌和食用方法