secrets --- 生�管�密�的安全�机数¶

在 3.6 版本加入.

�代�: Lib/secrets.py


secrets 模�用于生�高度加密的�机数,适于管�密��账户验��安全凭��机密数�。

最好用 secrets 替代 random 模�的默认伪�机数生�器,该生�器适用于建模和模拟,�宜用于安全与加密。

��

PEP 506

�机数¶

secrets 模�是�作系统�供的最安全地�机性��。

class secrets.SystemRandom¶

用�作系统�供的最高质��生��机数的类。详� random.SystemRandom。

secrets.choice(sequence)¶

返回一个从�空�列中�机选�的元素。

secrets.randbelow(n)¶

返回 [0, n) 范围内的�机整数。

secrets.randbits(k)¶

返回 k 个�机比特�的整数。

生� Token¶

secrets 模��供了生�安全 Token 的函数,适用于密��置�密� URL 等应用场景。

secrets.token_bytes([nbytes=None])¶

返回� nbytes 个字节的�机字节字符串。如果未�供 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'

Token 应当使用多少个字节?¶

为了在�对 暴力攻击 时��安全,Token 的�机性必须足够高。��计算机推�能力的�断��,�机性的安全标准也��断�高。比如 2015 年,32 字节(256 �)的�机性对于 secrets 模�的典型用例就已�足够了。

�自行管� Token 长度的用户,�以通过为 token_* 函数指定 int �数显�指定 Token �使用多大的�机性。该�数以字节数表示�机性大�。

�之,如果未�供�数,或�数为 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,包�密���应用的安全 Token:

import secrets
url = 'https://example.com/reset=' + secrets.token_urlsafe()