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])¶
返回一個包含 nbytes 個隨機位元組的隨機 URL 安全文字字串。文字是 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()