secrets --- 產生用於管理機密的安全亂數

在 3.6 版被加入.

原始碼:Lib/secrets.py


The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.

In particular, secrets should be used in preference to the default pseudo-random number generator in the random module, which is designed for modelling and simulation, not security or cryptography.

也參考

PEP 506

亂數

The secrets module provides access to the most secure source of randomness that your operating system provides.

class secrets.SystemRandom

一個用來產生亂數的類別,用的是作業系統提供的最高品質來源。 請參閱 random.SystemRandom 以取得更多細節。

secrets.choice(seq)

從一非空序列中,回傳一個隨機選取的元素。

secrets.randbelow(exclusive_upper_bound)

回傳一個 [0, exclusive_upper_bound) 範圍之內的隨機整數。

secrets.randbits(k)

回傳一個具 k 個隨機位元的非負整數。

產生權杖(token)

The secrets module provides functions for generating secure tokens, suitable for applications such as password resets, hard-to-guess URLs, and similar.

secrets.token_bytes([nbytes=None])

回傳一個隨機位元組字串,其中含有 nbytes 位元組的數字。 如果 nbytesNone 或未提供,則會使用一合理預設值。

>>> token_bytes(16)
b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
secrets.token_hex([nbytes=None])

回傳一以十六進位表示的隨機字串。 字串具有 nbytes 個隨機位元組,每個位元組會轉成兩個十六進位的數字。 如果 nbytesNone 或未提供,則會使用一個合理的預設值。

>>> token_hex(16)
'f9bf78b9a18ce6d46a0cd2b0b86df9da'
secrets.token_urlsafe([nbytes=None])

回傳一個 URL 安全的隨機文本字串,包含 nbytes 個隨機位元組。 文本將使用 Base64 編碼,因此平均來說每個位元組會對應到約 1.3 個字元。 如果 nbytesNone 或未提供,則會使用一個合理的預設值。

>>> token_urlsafe(16)
'Drmhze6EPcv0fN_81Bj-nA'

權杖應當使用多少個位元組?

To be secure against brute-force attacks, tokens need to have sufficient randomness. Unfortunately, what is considered sufficient will necessarily increase as computers get more powerful and able to make more guesses in a shorter period. As of 2015, it is believed that 32 bytes (256 bits) of randomness is sufficient for the typical use-case expected for the secrets module.

對於想自行管理權杖長度的使用者,你可以對各種 token_* 函式明白地指定 int 引數(argument)來指定權杖要使用的隨機性程度。 該引數以位元組數來表示要使用的隨機性程度。

否則,如未提供引數,或者如果引數為 None,則 token_* 函式則會使用一個合理的預設值。

備註

該預設值可能在任何時候被改變,包括在維護版本更新的時候。

其他函式

secrets.compare_digest(a, b)

如果字串或類位元組串物件 ab 相等則回傳 True,否則回傳 False,以"恆定時間比較 (constant-time compare) "的處理方式可降低時序攻擊的風險。 請參閱 hmac.compare_digest() 以了解更多細節。

應用技巧和典範實務(best practices)

This section shows recipes and best practices for using secrets to manage a basic level of security.

產生八個字元長的字母數字密碼:

import string
import secrets
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(8))

備註

應用程式不能以可復原的格式儲存密碼,無論是用純文本還是經過加密。 它們應當先加鹽(salt),再使用高加密強度的單向(不可逆)雜湊函式來產生雜湊值。

產生十個字元長的字母數字密碼,其中包含至少一個小寫字母,至少一個大寫字母以及至少三個數字:

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 風格的 passphrase:

import secrets
# 在標準 Linux 系統上,使用一個方便的字典檔案。
# 其他平台可能需要提供自己的字詞列表。
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()