django 1.8 官方文档翻译:8-5 加密签名
加密簽名
web應用安全的黃金法則是,永遠不要相信來自不可信來源的數據。有時通過不可信的媒介來傳遞數據會非常方便。密碼簽名后的值可以通過不受信任的途徑傳遞,這樣是安全的,因為任何篡改都會檢測的到。
Django提供了用于簽名的底層API,以及用于設置和讀取被簽名cookie的上層API,它們是web應用中最常使用的簽名工具之一。
你可能會發現,簽名對于以下事情非常有用:
生成用于“重置我的賬戶”的URL,并發送給丟失密碼的用戶。
確保儲存在隱藏表單字段的數據不被篡改,
生成一次性的秘密URL,用于暫時性允許訪問受保護的資源,例如用戶付費的下載文件。
保護 SECRET_KEY
當你使用 startproject創建新的Django項目時,自動生成的 settings.py文件會得到一個隨機的SECRET_KEY值。這個值是保護簽名數據的密鑰 -- 它至關重要,你必須妥善保管,否則攻擊者會使用它來生成自己的簽名值。
使用底層 API
Django的簽名方法存放于django.core.signing模塊。首先創建一個 Signer 的實例來對一個值簽名:
>>> from django.core.signing import Signer >>> signer = Signer() >>> value = signer.sign('My string') >>> value 'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w'這個簽名會附加到字符串末尾,跟在冒號后面。你可以使用unsign方法來獲取原始的值:
>>> original = signer.unsign(value) >>> original 'My string'如果簽名或者值以任何方式改變,會拋出django.core.signing.BadSignature 異常:
>>> from django.core import signing >>> value += 'm' >>> try: ... original = signer.unsign(value) ... except signing.BadSignature: ... print("Tampering detected!")通常,Signer類使用SECRET_KEY設置來生成簽名。你可以通過向Signer構造器傳遞一個不同的密鑰來使用它:
>>> signer = Signer('my-other-secret') >>> value = signer.sign('My string') >>> value 'My string:EkfQJafvGyiofrdGnuthdxImIJw'class Signer(key=None, sep=':', salt=None)[source]
返回一個signer,它使用key 來生成簽名,并且使用sep來分割值。sep 不能是 [URL安全的base64字母表(http://tools.ietf.org/html/rfc4648#section-5)]中的字符。字母表含有數字、字母、連字符和下劃線。
使用salt參數
如果你不希望對每個特定的字符串都生成一個相同的簽名哈希值,你可以在Signer類中使用可選的salt 參數。使用salt參數會同時用它和SECRET_KEY初始化簽名哈希函數:
>>> signer = Signer() >>> signer.sign('My string') 'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w' >>> signer = Signer(salt='extra') >>> signer.sign('My string') 'My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw' >>> signer.unsign('My string:Ee7vGi-ING6n02gkcJ-QLHg6vFw') 'My string'以這種方法使用salt會把不同的簽名放在不同的命名空間中。來自于單一命名空間(一個特定的salt值)的簽名不能用于在不同的命名空間中驗證相同的純文本字符串。不同的命名空間使用不同的salt設置。這是為了防止攻擊者使用在一個地方的代碼中生成的簽名后的字符串,作為使用不同salt來生成(和驗證)簽名的另一處代碼的輸入。
不像你的SECRET_KEY,你的salt參數可以不用保密。
驗證帶有時間戳的值
TimestampSigner是 Signer的子類,它向值附加一個簽名后的時間戳。這可以讓你確認一個簽名后的值是否在特定時間段之內被創建:
>>> from datetime import timedelta >>> from django.core.signing import TimestampSigner >>> signer = TimestampSigner() >>> value = signer.sign('hello') >>> value 'hello:1NMg5H:oPVuCqlJWmChm1rA2lyTUtelC-c' >>> signer.unsign(value) 'hello' >>> signer.unsign(value, max_age=10) ... SignatureExpired: Signature age 15.5289158821 > 10 seconds >>> signer.unsign(value, max_age=20) 'hello' >>> signer.unsign(value, max_age=timedelta(seconds=20)) 'hello'class TimestampSigner(key=None, sep=':', salt=None)[source]
sign(value)[source]
簽名value,并且附加當前的時間戳。
unsign(value, max_age=None)[source]
檢查value是否在少于max_age 秒之前被簽名,如果不是則拋出SignatureExpired異常。max_age 參數接受一個整數或者datetime.timedelta對象。
Changed in Django 1.8:在此之前, max_age參數只接受整數。保護復雜的數據結構
如果你希望保護一個列表、元組或字典,你可以使用簽名模塊的dumps 和 loads 函數來實現。它們模仿了Python的pickle模塊,但是在背后使用了JSON序列化。JSON可以確保即使你的SECRET_KEY被盜取,攻擊者并不能利用pickle的格式來執行任意的命令:
>>> from django.core import signing >>> value = signing.dumps({"foo": "bar"}) >>> value 'eyJmb28iOiJiYXIifQ:1NMg1b:zGcDE4-TCkaeGzLeW9UQwZesciI' >>> signing.loads(value) {'foo': 'bar'}由于JSON的本質(列表和元組之間沒有原生的區別),如果你傳進來一個元組,你會從signing.loads(object)得到一個列表:
>>> from django.core import signing >>> value = signing.dumps(('a','b','c')) >>> signing.loads(value) ['a', 'b', 'c']dumps(obj, key=None, salt='django.core.signing', compress=False)[source]
返回URL安全,sha1簽名的base64壓縮的JSON字符串。序列化的對象使用TimestampSigner來簽名。
loads(string, key=None, salt='django.core.signing', max_age=None)[source]
dumps()的反轉,如果簽名失敗則拋出BadSignature異常。如果提供了max_age則會檢查它(以秒為單位)。
譯者:Django 文檔協作翻譯小組,原文:Cryptographic signing。
本文以 CC BY-NC-SA 3.0 協議發布,轉載請保留作者署名和文章出處。
Django 文檔協作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
總結
以上是生活随笔為你收集整理的django 1.8 官方文档翻译:8-5 加密签名的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【jQuery】总结:筛选器、控制隐藏、
- 下一篇: 测试你的Python 水平----7