且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使 OpenSSL 生成确定性密钥

更新时间:2023-02-06 19:19:32

使 openssl 生成确定性密钥...

Making openssl generate deterministic key...

我不相信你可以开箱即用.默认情况下,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
", err);
    abort(); /* failed */
}

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

if(0 == rc) {
    fprintf(stderr, "ENGINE_init failed, err = 0x%lx
", 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
", 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.