secrets
— 生成安全的隨機數用於管理秘密¶
在 3.6 版本加入。
原始碼: Lib/secrets.py
secrets
模組用於生成加密強度高的隨機數,適用於管理密碼、賬戶認證、安全令牌和相關秘密等資料。
特別是,secrets
模組應優先於 random
模組中預設的偽隨機數生成器。後者設計用於建模和模擬,而非安全性或密碼學。
參見
隨機數¶
secrets
模組提供了對作業系統提供的最安全的隨機性來源的訪問。
- class secrets.SystemRandom¶
一個用於使用作業系統提供的最高質量來源生成隨機數的類。有關更多詳細資訊,請參閱
random.SystemRandom
。
- secrets.choice(seq)¶
從非空序列中返回一個隨機選擇的元素。
- secrets.randbelow(exclusive_upper_bound)¶
返回範圍 [0, exclusive_upper_bound) 內的一個隨機整數。
- secrets.randbits(k)¶
返回一個帶有 k 個隨機位的非負整數。
生成令牌¶
secrets
模組提供用於生成安全令牌的函式,適用於密碼重置、難以猜測的 URL 等應用程式。
- secrets.token_bytes([nbytes=None])¶
返回一個隨機位元組字串,包含 nbytes 個位元組。如果 nbytes 為
None
或未提供,則使用一個合理的預設值。>>> token_bytes(16) b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
- secrets.token_hex([nbytes=None])¶
返回一個隨機的十六進位制文字字串。該字串有 nbytes 個隨機位元組,每個位元組轉換為兩位十六進位制數字。如果 nbytes 為
None
或未提供,則使用一個合理的預設值。>>> token_hex(16) 'f9bf78b9a18ce6d46a0cd2b0b86df9da'
- secrets.token_urlsafe([nbytes=None])¶
返回一個 URL 安全的隨機文字字串,包含 nbytes 個隨機位元組。文字採用 Base64 編碼,因此平均每個位元組產生約 1.3 個字元。如果 nbytes 為
None
或未提供,則使用一個合理的預設值。>>> token_urlsafe(16) 'Drmhze6EPcv0fN_81Bj-nA'
令牌應使用多少位元組?¶
為了抵禦 暴力攻擊,令牌需要有足夠的隨機性。不幸的是,隨著計算機變得越來越強大,能夠在更短的時間內進行更多的猜測,所謂的“足夠”將必然增加。截至 2015 年,人們認為 32 位元組(256 位)的隨機性對於 secrets
模組所預期的典型用例是足夠的。
對於那些希望自行管理令牌長度的人,可以透過向各種 token_*
函式提供一個 int
引數來明確指定用於令牌的隨機性數量。該引數被視為要使用的隨機性位元組數。
否則,如果未提供引數,或引數為 None
,token_*
函式將使用合理的預設值。
備註
該預設值可能隨時更改,包括在維護版本中。
其他函式¶
- secrets.compare_digest(a, b)¶
如果字串或 類位元組物件 a 和 b 相等,則返回
True
,否則返回False
,使用“常數時間比較”來降低 定時攻擊 的風險。有關更多詳細資訊,請參閱hmac.compare_digest()
。
秘籍和最佳實踐¶
本節展示了使用 secrets
管理基本安全級別的秘籍和最佳實踐。
生成一個八個字元的字母數字密碼
import string
import secrets
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(8))
備註
應用程式不應 以可恢復的格式儲存密碼,無論是純文字還是加密的。它們應該使用加密強度高的一次性(不可逆)雜湊函式進行加鹽和雜湊處理。
生成一個十個字元的字母數字密碼,至少包含一個小寫字元、一個大寫字元和三個數字
import string
import secrets
alphabet = string.ascii_letters + string.digits
while True:
password = ''.join(secrets.choice(alphabet) for i in range(10))
if (any(c.islower() for c in password)
and any(c.isupper() for c in password)
and sum(c.isdigit() for c in password) >= 3):
break
生成一個 XKCD 風格的密碼短語
import secrets
# On standard Linux systems, use a convenient dictionary file.
# Other platforms may need to provide their own word-list.
with open('/usr/share/dict/words') as f:
words = [word.strip() for word in f]
password = ' '.join(secrets.choice(words) for i in range(4))
生成一個難以猜測的臨時 URL,其中包含一個適用於密碼恢復應用程式的安全令牌
import secrets
url = 'https://example.com/reset=' + secrets.token_urlsafe()