Skip to main content

secrets

secrets 模块用于生成密码学安全的随机数,适合管理密码、令牌、安全凭据等敏感数据。

secrets

info

secrets 应替代 random 模块用于安全场景。random 的伪随机数生成器可预测,仅适合建模和模拟。

随机数生成

import secrets

# 从序列中安全地随机选取一个元素
print(secrets.choice(["apple", "banana", "cherry"]))

# 生成 [0, n) 范围内的随机整数
print(secrets.randbelow(100))

# 生成 k 个随机位的整数
print(secrets.randbits(128))

生成安全令牌

令牌常用于密码重置链接、API 密钥、会话标识等场景。

import secrets

# 随机字节串
print(secrets.token_bytes(16))
# 例:b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'

# 十六进制令牌
print(secrets.token_hex(16))
# 例:'f9bf78b9a18ce6d46a0cd2b0b86df9da'

# URL 安全的令牌(Base64 编码)
print(secrets.token_urlsafe(16))
# 例:'Drmhze6EPcv0fN_81Bj-nA'
tip

不传参数时,令牌默认使用 secrets.DEFAULT_ENTROPY 字节的随机性。建议至少使用 32 字节(256 位)来抵御暴力破解。

生成随机密码

import string
import secrets

# 8 位字母数字密码
alphabet = string.ascii_letters + string.digits
password = "".join(secrets.choice(alphabet) for _ in range(8))
print(password)

带复杂度要求的密码(至少 1 个小写、1 个大写、3 个数字):

import string
import secrets

alphabet = string.ascii_letters + string.digits
while True:
password = "".join(secrets.choice(alphabet) for _ 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
print(password)

生成密码重置链接

import secrets

# 生成带安全令牌的临时 URL
url = "https://example.com/reset=" + secrets.token_urlsafe()
print(url)

安全比较

用常量时间比较两个字符串,防止计时攻击(timing attack)。

import secrets

token_stored = "abc123secure"
token_input = "abc123secure"

# 安全比较,避免通过响应时间推断内容
if secrets.compare_digest(token_stored, token_input):
print("令牌匹配")
else:
print("令牌不匹配")
info

普通的 == 比较在发现第一个不同字符时就会返回,攻击者可以通过测量响应时间逐字节猜测。compare_digest 始终比较完整长度,消除这一风险。