RAND_bytes不会从同一种子

时间:2016-12-22 13:20:23

标签: c openssl pbkdf2

我正在尝试使用OpenSSL编写自定义RSA密钥对生成算法。我已经使用PKCS5_PBKDF2_HMAC_SHA1函数生成PRNG种子,因此,我已将此种子用作RAND_seed输入。

不幸的是,每当我使用相同的种子调用RAND_bytes时,我会获得不同的随机数,但这不是预期的行为,因为正如How can one securely generate an asymmetric key pair from a short passphrase?的答案所示,随机数生成器是确定性的(相同的种子相同的输出)。

以下是测试用例。我已经宣布了恒定的种子,但这一代人从来都不是确定性的。

unsigned int seed = 0x00beef00;
unsigned int rnum[5];
RAND_seed(&seed, sizeof(seed));
RAND_bytes((unsigned char *)&rnum[0], sizeof(rnum));

错误在哪里?

2 个答案:

答案 0 :(得分:2)

这不是错误。 OpenSSL随机数生成器使用良好的随机源自行完成一些播种。

因此,在RAND_seed中使用相同的种子值并不能保证相同的随机数序列。这是一件好事,因为它使它们更难预测,因此更安全。

来自RAND_seed的手册页:

    #include <openssl/rand.h>

    void RAND_seed(const void *buf, int num);

    void RAND_add(const void *buf, int num, double entropy);

    int  RAND_status(void);

    int  RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam);
    void RAND_screen(void);
     

RAND_add()num的{​​{1}}字节混合到PRNG状态。因此,如果   buf的数据对对手来说是不可预测的,这会增加   关于国家的不确定性并使PRNG产出减少   可预测的。合适的输入来自用户交互(随机密钥   按下,鼠标移动)和某些硬件事件。 buf   参数是(下限)对随机性的估计   包含在buf中,以字节为单位。关于来源的详细信息   随机性和如何估计它们的熵可以在   文献,例如RFC 1750。

     可以使用用户输入的敏感数据调用

entropy   密码。种子值无法从PRNG中恢复   输出

     

OpenSSL确保每个线程的PRNG状态都是唯一的。   在提供“/ dev / urandom”的系统上,随机性设备是   用于透明地播种PRNG。但是,在所有其他系统上,   该申请负责通过电话播种PRNG   RAND_add()RAND_add()RAND_egd(3)

     当RAND_load_file(3)时,

RAND_seed()相当于RAND_add()

因此,如果您的系统有num == entropy,那么它将用作PRNG的初始种子。

答案 1 :(得分:-1)

Openssl的int RAND_bytes(unsigned char *buf, int num);试图让事情尽可能随意。这显然是你不想要的功能,而是寻找可重复的伪随机序列

但Openssl也有

int RAND_pseudo_bytes(unsigned char *buf, int num);

这可能是您正在寻找的,部分,为您提供可重复的序列。

https://linux.die.net/man/3/rand_pseudo_bytes

Force openssl's RNGs to return a repeatable byte sequence

顺便说一句,如果你正在做RSA,一个可重复的随机序列并不是那么好,因为你要找的是两个大素数。做一个大的PRNG号码,然后测试素数可能是一个坏主意。其中一半将被2整除! :)

如果我没记错的话,你需要选择一个好的起始编号,通过ORing 1使其变为奇数,然后测试素数,如果不是,则增加4并再试一次。

一旦找到它们,您可能不想再使用可重复的PRNG字节来开始搜索。

虽然我非常确定这是一个学习项目,但如果您想要的是来自openssl的RSA密钥对,请查看

https://stackoverflow.com/a/5246045/6047952