是否有推荐的方法在 OpenSSL 中生成随机字节并添加熵?
是的。请参阅 Random Numbers 上的 OpenSSL wiki。它会带您为种子添加熵,并提取字节以用于密钥和其他秘密材料。
为播种添加熵在Random Numbers and Seeds 中进行了介绍。 Random Numbers and Generation 介绍了提取用于密钥和其他机密材料的字节。
我在哪里可以获得其他引擎实现,以及如何交换它们?
OpenSSL 带有一些与随机数相关的引擎。默认是基于软件的 PRNG 引擎,md_rand。您可以在<openssl src>/crypto/rand/md_rand.c 找到它的源代码。另一个是英特尔的RDRAND 引擎。你可以在<openssl src>/crypto/engine/eng_rdrand.c找到源代码。
如果您有硬件,也可以使用基于硬件的 RNG。您甚至可以编写自己的引擎来提供 SHA-512 HMAC。甚至是一个将 SHA-512 HMAC 与RDRAND 结合(异或)的。 Mersenne Twister 很受欢迎,您甚至可以为它编写一个引擎。
以下是您如何更换引擎以用于随机数。它取自 OpenSSL wiki,并换入 Intel RDRAND 引擎:
1 unsigned long err = 0;
2 int rc = 0;
3
4 OPENSSL_cpuid_setup();
5 ENGINE_load_rdrand();
6
7 ENGINE* eng = ENGINE_by_id("rdrand");
8 err = ERR_get_error();
9
10 if(NULL == eng) {
11 fprintf(stderr, "ENGINE_load_rdrand failed, err = 0x%lx\n", err);
12 abort(); /* failed */
13 }
14
15 rc = ENGINE_init(eng);
16 err = ERR_get_error();
17
18 if(0 == rc) {
19 fprintf(stderr, "ENGINE_init failed, err = 0x%lx\n", err);
20 abort(); /* failed */
21 }
22
23 rc = ENGINE_set_default(eng, ENGINE_METHOD_RAND);
24 err = ERR_get_error();
25
26 if(0 == rc) {
27 fprintf(stderr, "ENGINE_set_default failed, err = 0x%lx\n", err);
28 abort(); /* failed */
29 }
30
31 /* OK to proceed */
32
33 ...
34 ENGINE_finish(eng);
35 ENGINE_free(eng);
36 ENGINE_cleanup();
...我正在尝试使用 OpenSSL 的 RAND_bytes API ...
除了正常使用RAND_bytes、RAND_add 和朋友之外,您永远不会做任何事情。您使用RAND_bytes、RAND_add 和朋友的方式永远不会改变。
Mersenne Twister 很受欢迎,您甚至可以为它编写引擎...
如果您这样做,那么您可能会考虑发布源代码供其他人使用。我建议在 OpenSSL 的 wiki 上创建一个页面,解释 Mersenne Twister 引擎,解释如何使用它,并为它提供补丁。
另一种选择是将其作为功能/增强功能提交给RT system(错误跟踪器)。但据我观察,大多数东西一旦进入 RT 就会枯萎死亡。