直接回答:现代 Linux(5.6+ 之后行为统一,此前的差异已成历史包袱):/dev/random 与 /dev/urandom 都来自同一个 CSPRNG( ChaCha20 内核随机器),区别仅在于历史上 /dev/random 会在“熵池耗尽”时阻塞——但密码学界早就澄清这个阻塞模型建立在错误的熵估计上,urandom 从未因此产生过实际弱输出。正确答案是:一律用 getrandom() 系统调用(或语言封装:Java 的 SecureRandom、Go 的 crypto/rand、Python 的 secrets),它在初始化完成前阻塞、之后永不阻塞。
展开解析:唯一需要操心的窗口是系统启动早期:内核 RNG 尚未收集到足够初始熵(虚拟机快照克隆、嵌入式无 RTC 设备、容器启动瞬间是高危场景),此时读 urandom 可能拿到可预测输出——getrandom() 的默认阻塞正是为此设计,阻塞说明系统在保护你而不是系统坏了。加固手段:virtio-rng 给虚拟机供熵、haveged/jitterentropy 兜底、RDRAND/RDSEED 指令(要评估对硬件后门的信任模型)。应用层纪律:密钥/令牌/盐一律 CSPRNG,Math.random、rand()、mt_rand 这类 PRNG 绝不出现在安全上下文;不要在进程里自己“再搅拌”系统随机数(画蛇添足还引入 bug);随机数生成失败要 crash 而不是降级到时间戳种子。历史上的真实事故(Debian OpenSSL 2008 年把熵源注释掉导致全网弱密钥)说明这个领域“看起来能跑”与“密码学安全”之间隔着深渊。
追问方向:虚拟机快照恢复后 RNG 状态重复怎么办?容器里的熵是共享的吗?
(约 480 字)