我正在尝试使用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));
错误在哪里?
答案 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密钥对,请查看