secrets模块提供密码学安全随机数,random模块仅适用于非安全场景;前者调用系统熵源不可预测,后者基于可逆Mersenne Twister算法易被预测;涉及密钥、token等敏感值必须用secrets。

Python 的 secrets 模块专为生成密码学安全的随机数而设计,而 random 模块使用的是伪随机数生成器(PRNG),不适用于安全敏感场景。
核心差异:是否满足密码学安全要求
random 基于 Mersenne Twister 算法,速度快、可复现,但输出可被预测——只要知道初始状态(seed)和部分输出,就能推算后续所有值。它适合模拟、游戏、测试等非安全用途。secrets 则直接调用操作系统提供的加密安全随机源(如 Linux 的 /dev/urandom、Windows 的 BCryptGenRandom),其输出不可预测、不可重现,满足密码学强度要求。
典型误用场景与正确替代方式
以下操作若用于身份凭证、密钥或令牌生成,random 是危险的:
- 生成 API 密钥:
random.choice(letters * 16)→ 应改用secrets.token_urlsafe(32) - 生成密码重置码:
random.randint(1000, 9999)→ 应改用secrets.randbelow(9000) + 1000 - 随机选用户盐值:
random.getrandbits(128)→ 应改用secrets.randbits(128)
为什么不能简单“加个 seed”让 random 变安全
即使使用 os.urandom 给 random.seed() 提供真随机种子,Mersenne Twister 内部状态仍可被逆向恢复——已有成熟攻击方法可在获取约 624 个输出后完全重建状态。这与 secrets 的设计目标根本不同:secrets 不维护内部状态,每次调用都独立采样操作系统熵池。
立即学习“Python免费学习笔记(深入)”;
实际开发中的选择建议
记住一个简单原则:凡涉及“别人不该猜到”的值,就用 secrets;仅用于“看起来随机就行”的场合,才用 random。
- 用
secrets:密码、token、salt、验证码、加密密钥、会话 ID - 用
random:洗牌测试数据、蒙特卡洛模拟、图形噪声、抽样统计
不复杂但容易忽略。










