RANDOM - Linux手册页

时间:2019-08-20 18:01:47  来源:igfitidea点击:

Linux程序员手册 第4部分
更新日期: 2017-09-15

名称

random,urandom-内核随机数源设备

语法

#包括

int ioctl(fd,RNDrequest,param);

说明

特殊字符字符文件/ dev / random和/ dev / urandom(从Linux 1.3.30开始存在)提供了到内核的随机数生成器的接口。文件/ dev / random具有主要设备号1和次要设备号8。文件/ dev / urandom具有主要设备号1和次要设备号9。

随机数发生器将来自设备驱动程序和其他来源的环境噪声收集到一个熵池中。发生器还保持熵池中噪声位数的估计。从这个熵池中,创建随机数。

Linux 3.17和更高版本提供了更简单,更安全的getrandom(2)接口,该接口不需要特殊文件。有关详细信息,请参见getrandom(2)手册页。

读取时,/ dev / urandom设备使用从熵池中植入的伪随机数生成器返回随机字节。从该设备进行的读取不会阻塞(即未产生CPU),但是在请求大量数据时可能会引起明显的延迟。

在早期引导期间读取时,/ dev / urandom可能会在初始化熵池之前返回数据。如果您的应用程序中有此问题,请改用getrandom(2)或/ dev / random。

/ dev / random设备是一个旧式接口,其历史可以追溯到/ dev / urandom实施中使用的加密原语未被广泛信任的时期。它将仅在熵池中新鲜噪声的估计位数内返回随机字节,如有必要,将进行阻塞。 / dev / random适用于需要高质量随机性的应用程序,并且可以提供不确定的延迟。

当熵池为空时,从/ dev / random的读取将被阻塞,直到收集到其他环境噪声为止。如果使用O_NONBLOCK标志为/ dev / random调用open(2),则在请求的字节数不可用时,后续的read(2)将不会阻塞。而是返回可用字节。如果没有可用字节,read(2)将返回-1,并且errno将设置为EAGAIN。

当打开/ dev / urandom时,O_NONBLOCK标志无效。当为设备/ dev / urandom调用read(2)时,最多256个字节的读取将返回请求的字节数,并且不会被信号处理程序中断。如果被信号处理程序中断,则超过此限制的缓冲区读取可能返回的字节数少于请求的字节数,或者失败并显示错误EINTR。

从Linux 3.16开始,/ dev / urandom的read(2)将最多返回32 MB。 / dev / random的read(2)最多返回512字节(在2.6.12版之前的Linux内核上为340字节)。

写入/ dev / random或/ dev / urandom将使用写入的数据更新熵池,但这不会导致较高的熵计数。这意味着它将影响从两个文件读取的内容,但不会使从/ dev / random的读取更快。

Usage

/ dev / random接口被认为是旧版接口,/ dev / urandom在所有用例中都是首选且足够,除非在早期启动时需要随机性的应用程序除外;对于这些应用程序,必须改用getrandom(2),因为它会阻塞直到初始化熵池。

如果按以下建议在重新启动后保存了种子文件,则在启动顺序中重新加载输出后,该输出将通过密码安全地保护攻击者,而无需本地root用户访问,并且完全适合网络加密会话密钥。 (至少从2000年开始,所有主要的Linux发行版都至少在重新启动后保存了种子文件。)由于从/ dev / random的读取可能会阻塞,因此用户通常希望以非阻塞模式打开它(或执行超时读取),并提供一些内容。如果所需的熵不是立即可用的,则通知用户。

Configuration

如果您的系统尚未创建/ dev / random和/ dev / urandom,则可以使用以下命令创建它们:

mknod -m 666 /dev/random c 1 8
mknod -m 666 /dev/urandom c 1 9
chown root:root /dev/random /dev/urandom

当Linux系统在没有太多操作员交互的情况下启动时,熵池可能处于相当可预测的状态。这将熵池中的实际噪声量降低到估计值以下。为了抵消这种影响,它有助于在关闭和启动之间传递熵池信息。为此,请将这些行添加到在Linux系统启动过程中运行的适当脚本中:

echo "Initializing random number generator..."
random_seed=/var/run/random-seed
# Carry a random seed from start-up to start-up
# Load and then save the whole entropy pool
if [ -f $random_seed ]; then
    cat $random_seed >/dev/urandom
else
    touch $random_seed
fi
chmod 600 $random_seed
poolfile=/proc/sys/kernel/random/poolsize
[ -r $poolfile ] && bits=$(cat $poolfile) || bits=4096
bytes=$(expr $bits / 8)
dd if=/dev/urandom of=$random_seed count=1 bs=$bytes

另外,在Linux系统关闭期间运行的适当脚本中添加以下行:

# Carry a random seed from shut-down to start-up
# Save the whole entropy pool
echo "Saving random seed..."
random_seed=/var/run/random-seed
touch $random_seed
chmod 600 $random_seed
poolfile=/proc/sys/kernel/random/poolsize
[ -r $poolfile ] && bits=$(cat $poolfile) || bits=4096
bytes=$(expr $bits / 8)
dd if=/dev/urandom of=$random_seed count=1 bs=$bytes

在以上示例中,我们假设使用Linux 2.6.0或更高版本,其中/ proc / sys / kernel / random / poolsize返回以位为单位的熵池的大小(请参见下文)。

/proc interfaces

目录/ proc / sys / kernel / random(从2.3.16开始存在)中的文件提供了有关/ dev / random设备的其他信息:

entropy_avail
该只读文件以位为单位提供可用的熵。这是介于0到4096之间的数字。
poolsize
This file gives the size of the entropy pool. The semantics of this file vary across kernel versions:
Linux 2.4:
该文件以字节为单位给出了熵池的大小。通常,此文件的值将为512,但是它是可写的,并且可以更改为可用算法的任何值。选项是32、64、128、256、512、1024或2048。
Linux 2.6 and later:
该文件是只读文件,并以位为单位给出熵池的大小。它包含值4096。
read_wakeup_threshold
该文件包含唤醒从/ dev / random进入等待熵的睡眠过程所需的熵位数。默认值为64。
write_wakeup_threshold
该文件包含熵的位数,在此之下,我们唤醒执行select / 2或poll(2)的进程以对/ dev / random进行写访问。可以通过写入文件来更改这些值。
uuidand boot_id
这些只读文件包含随机字符串,例如6fd5a44b-35f4-4ad4-a9b9-6b9be13e1fe9。每次读取前都会重新生成前者,而后者则只生成一次。

ioctl(2) interface

以下ioctl(2)请求是在连接到/ dev / random或/ dev / urandom的文件描述符上定义的。所有执行的请求都将与输入熵池交互,从而影响/ dev / random和/ dev / urandom。除RNDGETENTCNT之外的所有请求都需要CAP_SYS_ADMIN功能。

RNDGETENTCNT
检索输入池的熵计数,其内容将与proc下的entropy_avail文件相同。结果将存储在参数所指向的int中。
RNDADDTOENTCNT
按参数指向的值增加或减少输入池的熵计数。
RNDGETPOOL
在Linux 2.6.9中已删除。
RNDADDENTROPY
向输入池中添加一些附加的熵,从而增加熵计数。这与写入/ dev / random或/ dev / urandom有所不同,后者仅添加一些数据,而不增加熵计数。使用以下结构:
struct rand_pool_info {
    int    entropy_count;
    int    buf_size;
    __u32  buf[0];
};
这里的entropy_count是添加到熵计数(或从中减去)的值,而buf是大小为buf_size的缓冲区,该缓冲区被添加到熵池中。
RNDZAPENTCNT, RNDCLEARPOOL
将所有池的熵计数清零,然后向池中添加一些系统数据(例如壁钟)。

文件

/ dev /随机
/ dev / urandom

备注

有关可用于获得随机性的各种接口的概述和比较,请参见random(7)。

BUGS

在早期启动期间,从/ dev / urandom读取可能会在初始化熵池之前返回数据。

另外参见

mknod(1),getrandom(2),random(7)

RFC 1750,"安全性随机性建议"

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/