首页/网络/协议速查/随机数与熵源

随机数与熵源

密钥、nonce、会话 ID 全依赖高质量随机:/dev/urandom(getrandom)是 Linux 上的正确来源;自造随机数(时间戳/rand())是事故重灾区。

协议速查网络更新于 2026-10-13

随机数与熵源是干什么的

密钥、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 密钥完全相同的案例。批量部署后应逐台校验公钥指纹是否唯一。

易错点

  • 用 rand() 或时间戳生成 token:可被枚举,直接导致会话劫持或账号接管
  • 虚拟机快照克隆后不重新生成密钥:多台实例密钥相同,等于一把钥匙开所有门
  • 认为 /dev/urandom 不安全而坚持用 /dev/random:后者在高负载下阻塞,会拖慢服务建连甚至卡住启动
  • 容器重启复用持久化的随机种子文件:跨实例复用会削弱不可预测性

数据来源与参考

  • man 2 getrandom
  • NIST SP 800-90A/B

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌