【发布时间】:2013-10-09 08:38:10
【问题描述】:
我打算使用 /dev/random 输出作为 openssl 密钥生成的种子,然后我编写了这个小程序来检查我要做什么:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#define LEN 128
void uc2hex(char* hex, unsigned char* uc, unsigned short uc_len)
{
FILE* bp=fmemopen(hex,2*uc_len+1,"w");
unsigned short i;
for(i=0;i<uc_len;i++)
{
fprintf(bp,"%02x",uc[i]);
//printf("%02x\n",uc[i]);
//fprintf(bp,"%d-",i);
}
fprintf(bp,"%c",'\0');
fclose(bp);
}
int main()
{
unsigned char buf[LEN];
char str[2*LEN+1];
int fd=open("/dev/random",O_RDONLY);
read(fd,buf,LEN);
uc2hex(str,buf,LEN);
printf("%s\n",str);
close(fd);
return 0;
}
我运行程序一到两次,一切似乎都运行良好,但随后我又在短时间内再次运行了四次,这是输出:
[walter@eM350 ~]$ ./random
0ee08c942ddf901af1278ba8f335b5df8db7cf18e5de2a67ac200f320a7a20e84866f533667a7e66a4572b3bf83d458e6f71f325783f2e3f921868328051f8f296800352cabeaf00000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000
[walter@eM350 ~]$ ./random
1f69a0b931c16f796bbb1345b3f58f17f74e3df600000000bb03400000000000ffffffff00000000880e648aff7f0000a88103b4d67f000000305cb4d67f000030415fb4d67f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000
[walter@eM350 ~]$ ./random
4e8a1715238644a840eb66d9ff7f00002e4e3df600000000bb03400000000000ffffffff00000000a8ec66d9ff7f0000a871a37ad97f00000020fc7ad97f00003031ff7ad97f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000
[walter@eM350 ~]$ ./random
598c57563e8951e6f0173f0cff7f00002e4e3df600000000bb03400000000000ffffffff0000000058193f0cff7f0000a8e1cbda257f0000009024db257f000030a127db257f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000
在我看来,除了 128 字节的随机字符串之外,这些都是一样的,因为它们几乎是相同的。然后,排除 NSA 篡改 linux 内核随机数生成器的可能性,我只能猜测这与我机器中的可用熵有关,当我按顺序询问太多字节时,它会耗尽。我的问题是: 1)这个猜测正确吗? 2)假设1)是正确的,我怎么知道是否有足够的熵来生成真正的随机字节序列?
【问题讨论】:
-
使用
/dev/urandom。真正的随机性是稀缺的,不应该那样浪费。 -
@KerrekSB 定义“浪费”。如果我从
/dev/urandom阅读,熵数也会减少。不同之处在于,如果计数达到 0,urandom不会停止。 -
@glglgl:不同之处在于
urandom使用真正的随机性来播种伪随机性。确实,如果有更多可用随机性,您会获得更好的随机性,但伪随机性至少与给定可用随机性一样好。 -
@KerrekSB 我知道这一点,但我的印象是使用
urandom也会消耗熵(从而干扰random)。但似乎他们使用了两个完全不同的熵池。