发布网友 发布时间:2024-12-29 06:53
共1个回答
热心网友 时间:2024-12-31 04:49
/dev/random 和 /dev/urandom 是 Linux 上的字符设备文件,它们是随机数生成器,为系统提供随机数。
随机数在计算中非常重要,例如 TCP/IP 序列号、密码盐和 DNS 源端口号都依赖于随机数。在密码学中,随机性无处不在,从密钥生成到加密系统,甚至密码系统受到攻击的方式。没有随机性,所有加密操作都是可预测的,因此不安全。
为了尽可能地做到随机,随机数生成器会收集系统环境中各种数据,如鼠标的移动、键盘的输入、终端的连接和断开、音视频的播放、系统中断、内存和 CPU 的使用等。这些数据会被放入一个熵池中,然后进行去偏、漂白,目的是使数据更加无序,难以猜测。
有了大量的环境数据后,每次获取随机数时,从池子中读取指定的字节序列,这些字节序列就是生成器生成的随机数。
随机数生成器的结构分为收集器、主熵池、次熵池、urandom 熵池、计数器等部分。收集器收集系统中的环境噪音,如鼠标、键盘、中断事件、内存、CPU等,并进行批量去偏、漂白,进入主熵池中。主熵池为次熵池和 urandom 熵池提供随机数,大小为 512字节(4098二进制位)。
在 Linux 上,可以通过命令查看当前系统主熵池的大小,单位为二进制位的数量。
/dev/random 设备关联,大小为 128 字节,它是阻塞的。/dev/urandom 设备关联,大小也为 128 字节,它是非阻塞的。
主熵池、次熵池以及 urandom 熵池各自都有一个计数器,用于记录当前熵池中可用随机数的数量。当熵池中有新的随机数加入时,对应熵池的计数器计数增加;当熵池中随机数被取出时,熵池计数器计数减少。
生成器主要有 /dev/random、/dev/urandom、get_random_bytes() 这三个接口,可以从用户空间访问这两设备文件,即使是普通用户也有访问权限。它们返回指定请求数量的随机数。
请求随机数的流程如下:urandom 熵池计数器计数减去 N,如果结果大于等于 0,直接从 urandom 熵池中取出 N 个随机二进制位并返回;如果结果小于 0,请求不会阻塞,返回的是 N 个伪随机二进制位。次熵池计数器减去 N,如果结果大于等于 0,直接从次熵池中取出 N 个随机二进制位并返回;如果结果小于 0,先从主熵池提取剩余所需的随机二进制位,主熵池计数器减去相应的值,同时返回 N 个随机二进制位。如果这时主熵池和次熵池两者计数器之和都不够 N 的话,读取随机二进制位的动作会被阻塞,直到次熵池中有足够的随机二进制位。
/dev/random 和 /dev/urandom 的区别在于,/dev/urandom 返回指定请求数量的随机数,如果请求的数量非常庞大,返回的随机数可能是伪随机数,随机数质量稍差。/dev/random 也是返回指定请求数量的随机数,但产生的随机数质量很高,是真随机数,主要用于需要高质量随机数的地方,如生成加密密钥。
为了保证随机数的质量,/dev/random 只能返回熵池当前最大可用的随机二进制位,当请求超过这个值,就会阻塞,直到熵池中有足够的随机二进制位。
/dev/random 和 /dev/urandom 都是 Linux 上的随机数生成器,应用中选择哪一个取决于具体的使用场景。/dev/random 产生的随机数质量高,主要用于安全方面,但它是阻塞的,对于大部分应用来说,这是不能接受的。/dev/urandom 当熵池计数器足够时,产生真随机数;计数不够时,产生伪随机数。最重要的是,它不会阻塞,对于绝大多数应用来说,伪随机数也能很好地满足需求。
本文主要介绍了 Linux 下 /dev/random 和 /dev/urandom 两种随机数生成器的原理以及区别。更多细节知识,请自行查阅 man 文档或参考相关链接。