随机数与熵源是干什么的
密钥、nonce、会话 ID、盐值全部依赖高质量随机数。Linux 上的正确来源是 getrandom(2) 系统调用与 /dev/urandom,它们背后是基于 ChaCha20 之类算法的密码学随机数发生器,初始化完成后不再阻塞。macOS 与 BSD 对应 /dev/urandom 和 getentropy,Windows 用 BCryptGenRandom。用时间戳、rand() 或 UUIDv1 充当随机源,是安全事故的常见起点。
基本信息
| 适用平台 | Linux / macOS / Windows,接口不同 |
|---|---|
| 内核正确来源 | getrandom(2)、/dev/urandom |
| 历史区别 | /dev/random 曾在熵池不足时阻塞,现代内核已基本不再区分 |
| 命令行生成 | openssl rand 默认走密码学安全发生器 |
| 严禁使用 | 时间戳、rand()、Math.random()、UUIDv1、进程号拼接 |
| 典型用途 | 密钥、nonce、会话 token、密码重置令牌、盐值 |
典型使用场景
- 生成密钥与 IV/nonce:加密库的密钥生成都应走 CSPRNG
- 会话与接口 token:登录态、CSRF token、一次性链接必须不可预测
- 密码学盐值:每个用户独立盐,避免彩虹表与同密文识别
- 虚拟机与容器部署:克隆后校验各实例密钥是否唯一
- 合规审计:证明随机源达到密码学强度要求
检查与生成
检查与生成
# 查看传统熵池可用位数(现代内核仅供参考)
cat /proc/sys/kernel/random/entropy_avail
# 生成 32 字节随机并转十六进制
openssl rand -hex 32
# 直接读内核随机源再以十六进制查看
head -c 32 /dev/urandom | xxd
# 下面这种写法可预测,禁止用于任何安全用途
date +%s%N随机源强度对照
| 来源 | 强度 | 结论 |
|---|---|---|
| getrandom(2) / /dev/urandom | 密码学强度,不可预测 | 首选 |
| /dev/random | 历史上有阻塞问题,安全性无额外优势 | 多数场景无需使用 |
| rand() / Math.random() | 伪随机,种子可推测 | 禁止用于安全用途 |
| 时间戳与进程号拼接 | 熵极低 | 禁止用于密钥与令牌 |
Linux 5.6 起 getrandom 在系统极早期即可用,容器与 systemd 环境下通常无需再担心启动期熵不足;早期「熵池不够」的经验主要针对 /dev/random。
从同一虚拟机快照克隆出的实例可能拿到相同的随机种子,历史上出现过大批设备 SSH 密钥完全相同的案例。批量部署后应逐台校验公钥指纹是否唯一。