本文介绍了使OpenSSL生成确定性密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使openssl生成确定性的专用和公用RSA密钥对.我的想法是,我用一些与设备相关的数据的HASH填充我的seedbuf,并将其用作种子.但是播种RAND似乎无效,密钥仍然是随机的.

I'm trying to make openssl generate deterministic private and public RSA key-pair. The idea is that I fill my seedbuf with a HASH of some device dependent data, and use that as a seed. But seeding the RAND does not seem to work, the keys are still randomized.

出于各种原因,我不想只生成一次密钥然后再存储它,我只希望私钥存在于内存中.

For various reasons I don't want to just generate the key once, and then store it, I only want the private key to exist in memory.

RAND_seed(seedbuf, sizeof(seedbuf));

bne = BN_new();
if (1 != BN_set_word(bne,e)) {
    goto free_stuff;
}

keypair = RSA_new();
if(1 != RSA_generate_key_ex(keypair, KEY_LENGTH, bne, NULL)) {
    goto free_stuff;
}

所以基本上,我希望"RSA_generate_key_ex"函数每次以相同的输入作为种子时都返回相同的密钥对.

So basically I want the "RSA_generate_key_ex" function to return same key-pair, each time it is seeded with same input.

推荐答案

我不认为您可以开箱即用.默认情况下,OpenSSL使用md_rand,并且自动将其自身设定为种子.在内部调用rand_seed会调用rand_add,这会增加状态(而不是丢弃/替换状态).您可以在crypto/rand/md_rand.c中找到md_rand的来源.

I don't believe you can do it out of the box. By default, OpenSSL uses md_rand, and that auto seeds itself. Calling rand_seed internally calls rand_add, which adds to the state (rather than discarding/replacing state). You can find the source for md_rand in crypto/rand/md_rand.c.

如果在启用FIPS的情况下进行构建,则可以使用NIST SP 800-90中的确定性随机位生成器.但是,我似乎还记得它们以与md_rand相似的方式工作.也就是说,您可以添加到内部状态,但不能真正控制它.您可以在crypto/rand/rand_lib.c中找到源.

If you build with FIPS enabled, then there are deterministic random bit generators from NIST's SP 800-90. However, I seem to recall they operate in similar fashion to md_rand. That is, you can add to internal state, but you can't really control it. You can find the source in crypto/rand/rand_lib.c.

我认为您有一个选择.您可以创建自己的my_rand.基于分组密码或哈希.启动时,将其与设备相关的数据作为种子,然后返回确定性字节.

I think you have one option. You can create you own my_rand. Base it on a block cipher or hash. On startup, seed it with device dependent data, and then return the deterministic bytes.

现在,要使用RSA_generate_key_ex之类的功能来使用PRNG,您必须将其打包在OpenSSL ENGINE中. OpenSSL的Richard Levitte在引擎构建第1课:一种最低限度的无用引擎引擎构建课程2:OpenSSL博客上的MD5引擎示例.

Now, to get functions like RSA_generate_key_ex to use your PRNG, you have to package it in an OpenSSL ENGINE. Richard Levitte of OpenSSL has a nice two-series blog at Engine Building Lesson 1: A Minimum Useless Engine and Engine Building Lesson 2: An Example MD5 Engine on the OpenSSL blog.

一旦将其与引擎打包在一起,就可以像这样使用它.用ENGINE_METHOD_RAND设置随机方法后,将使用您的算法.

Once you package it with an engine, you can use it like so. After you set the random method with ENGINE_METHOD_RAND, you will be using your algorithm.

ENGINE* eng = ENGINE_by_id("my_rand");
unsigned long err = ERR_get_error();

if(NULL == eng) {
    fprintf(stderr, "ENGINE_by_id failed, err = 0x%lx\n", err);
    abort(); /* failed */
}

int rc = ENGINE_init(eng);
err = ERR_get_error();

if(0 == rc) {
    fprintf(stderr, "ENGINE_init failed, err = 0x%lx\n", err);
    abort(); /* failed */
}

rc = ENGINE_set_default(eng, ENGINE_METHOD_RAND);
err = ERR_get_error();

if(0 == rc) {
    fprintf(stderr, "ENGINE_set_default failed, err = 0x%lx\n", err);
    abort(); /* failed */
}

如果要查看ENGINE实现,请查看crypto/engine/eng_rdrand.c中的rdrand引擎.引擎没有太多功能,并且很容易复制/粘贴.确保将新引擎添加到crypto/engine/Makefile中的Makefile.

If you want to look at a ENGINE implementation, take a look at the rdrand engine in crypto/engine/eng_rdrand.c. There's not much to the engine, and it will be easy to copy/paste. Be sure to add your new engine to the Makefile in crypto/engine/Makefile.

这篇关于使OpenSSL生成确定性密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 22:11
查看更多