secrets --- 生成管理密码的安全随机数¶
Added in version 3.6.
源代码: Lib/secrets.py
secrets 模块用于生成高度加密的随机数,适于管理密码、账户验证、安全凭据以及相关的加密数据。
具体而言,应当使用 secrets 来代替 random 模块中的默认伪随机数生成器,后者被设计用于建模和模拟,而不宜用于安全或加密。
参见
随机数¶
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)¶
Return a random byte string containing nbytes number of bytes.
If nbytes is not specified or
None,DEFAULT_ENTROPYis used instead.>>> token_bytes(16) b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
- secrets.token_hex(nbytes=None)¶
Return a random text string, in hexadecimal. The string has nbytes random bytes, each byte converted to two hex digits.
If nbytes is not specified or
None,DEFAULT_ENTROPYis used instead.>>> token_hex(16) 'f9bf78b9a18ce6d46a0cd2b0b86df9da'
- secrets.token_urlsafe(nbytes=None)¶
Return a random URL-safe text string, containing nbytes random bytes. The text is Base64 encoded, so on average each byte results in approximately 1.3 characters.
If nbytes is not specified or
None,DEFAULT_ENTROPYis used instead.>>> token_urlsafe(16) 'Drmhze6EPcv0fN_81Bj-nA'
Token 应当使用多少个字节?¶
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 长度的用户,可以通过为 token_* 函数指定 int 参数显式指定 Token 要使用多大的随机性。该参数以字节数表示随机性大小。
Otherwise, if no argument is provided, or if the argument is None,
the token_* functions use DEFAULT_ENTROPY instead.
- secrets.DEFAULT_ENTROPY¶
token_*函数所使用的默认随机字节数。该值可能随时发生变化,包括在维护版本发布的时候。
其他函数¶
- secrets.compare_digest(a, b)¶
Return
Trueif strings or bytes-like objects a and b are equal, otherwiseFalse, using a "constant-time compare" to reduce the risk of timing attacks. Seehmac.compare_digest()for additional details.
应用技巧与最佳实践¶
本节展示了一些使用 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
# 在标准 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))
生成包含安全 Token 的难以猜测的临时 URL,适用于密码恢复应用:
import secrets
url = 'https://example.com/reset=' + secrets.token_urlsafe()