如何生成真随机数?Coursebook /dev/random 与 /dev/urandom 实用指南
【免费下载链接】coursebookOpen Source Introductory Systems Programming Textbook for the University of Illinois项目地址: https://gitcode.com/GitHub_Trending/co/coursebook
🎲 在 Linux 系统中生成随机数,最"正统"的方式不是写算法,而是直接读取内核设备文件/dev/random和/dev/urandom。这篇文章基于开源教材Coursebook——伊利诺伊大学厄巴纳-香槟分校(UIUC)CS 341 系统编程课程的官方课本,用通俗易懂的方式带你搞懂:什么是熵、真随机数与伪随机数有何区别、该选哪个设备文件,以及如何避免在生产环境中踩坑。
什么是真随机数?先搞懂"熵"这个概念
**熵(Entropy)**可以理解为"不可预测性"的度量。真随机数生成器(TRNG)从环境噪声中采集熵——比如磁盘 I/O 完成时间、中断到达时间、鼠标移动等物理世界的"杂音"。
Coursebook 在 filesystems/filesystems.tex 的 "Obtaining Random Data" 一节给出了精炼定义:
/dev/random:一个随机数生成器文件,其熵来源于环境噪声;如果熵池不够,它会阻塞等待,直到采集到足够的环境熵才返回数据。/dev/urandom:与 random 类似,但熵阈值更低、允许重复,因此永远不会阻塞。
一个关键心智模型:两者都不是"有开头和结尾的普通文件",而是无限的数据流——你可以像读文件一样从里面不断读取随机字节。
/dev/random vs /dev/urandom:一张表看懂区别
| 特性 | /dev/random | /dev/urandom |
|---|---|---|
| 熵来源 | 环境噪声,要求更高 | 同源,但熵阈值更低 |
| 是否会阻塞 | ⚠️ 会,熵不足时卡住 | ✅ 不会 |
| 典型用途 | 系统启动阶段需要密码学安全数据的极少数场景 | 绝大多数场景的首选 |
| 跨平台 | macOS 等系统没有"真" random | 几乎所有 Unix 类系统都有 |
💡课程书给出的核心结论:99% 的情况下你应该用/dev/urandom。
快速上手:在终端读取真随机数
不需要写任何代码,两条命令就能体验随机数据流:
# 把 /dev/urandom 的 1 MiB 随机数据"倒"进黑洞(虚拟文件) $ dd if=/dev/urandom of=/dev/null bs=1k count=1024 # 抓取 20 行随机字节流,head 数够换行符就退出 $ cat /dev/urandom | head -n 20第二条命令还顺便演示了管道的经典行为:head读完 20 行就终止,cat因无人监听管道而收到SIGPIPE信号——这个细节在 ipc/ipc.tex 中作为管道信号机制的示例被讲解。
小知识:
dd命令在 Coursebook 中被列为复制文件、制作磁盘镜像的瑞士军刀,参见 filesystems/filesystems.tex 的 "Copying Files" 一节。
为什么大部分时候不该用 /dev/random?
这是本文最值得记住的部分。教材列出了 4 个务实的理由:
- 实测两者输出都"够随机",日常场景难以区分;
/dev/random可能在最糟糕的时机阻塞:如果你的高并发服务依赖它,攻击者可以刻意耗尽熵池,让你的服务集体卡死——这是一次可被利用的拒绝服务(DoS);- 手册作者提到的"耗尽熵池后猜出种子位"攻击,至今仍是理论假设,从未被实现;
- 安全专家认为
/dev/urandom已经是"计算安全"级别——现代加密算法本身只依赖计算安全性,/dev/urandom完全够用。
⚠️ 唯一例外:系统刚启动时、熵池尚未建立、又必须生成密码学安全密钥的场景,才考虑/dev/random的阻塞式保障。
真随机数在系统里的真实用途
随机数不只是"掷骰子",内核和安全机制大量依赖它。Coursebook 中有两处精彩实例:
🔐 TCP 序列号随机化:TCP 三次握手时,连接的初始序列号(ISN)从一个随机整数开始。如果 ISN 可预测,攻击者就能伪造连接——这正是安全领域的经典防御设计。
🛡️ ASLR 地址空间随机化:进程的代码段、堆、栈、库的基地址每次运行都从随机值开始,让攻击者难以"对号入座"进行 return-to-libc 攻击,详见 security/security.tex。
而在应用层,教材的 sleep sort 示例用rand() % 5生成随机等待秒数,配合srand(time(NULL))播种,见 synchronization/synchronization.tex——注意:C 库的rand()只是伪随机,安全敏感场景请回到/dev/urandom。
总结:3 句话带走真随机数知识
- ✅选设备文件:日常开发和密码学场景一律
/dev/urandom,只有启动期密钥生成考虑/dev/random。 - ✅防 DoS:别在高并发服务里同步读
/dev/random,熵池耗尽会被攻击者武器化。 - ✅想深入:阅读 Coursebook 的文件系统章节(filesystems/filesystems.tex)与安全章节(security/security.tex),前者系统讲解
/dev/random、/dev/urandom、/proc、/sys,后者讲透 ASLR 与 TCP 随机化。
学有余力?试试教材课后题:"What are /sys, /proc, /dev/random, and /dev/urandom?"(filesystems/filesystems.tex)——能答上来,说明你真懂了!
【免费下载链接】coursebookOpen Source Introductory Systems Programming Textbook for the University of Illinois项目地址: https://gitcode.com/GitHub_Trending/co/coursebook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考