在我看到的所有示例中,使用EVP高级函数通过OpenSSL使用椭圆曲线生成密钥,需要两个EVP_PKEY_CTX
和EVP_PKEY
(总共4个)变量:< / p>
是否有可能将两者合并为一对密钥/上下文对?据我了解,从我所看到的示例中,逻辑是这样的:
EVP_PKEY_CONTEXT
。EVP_PKEY_paramgen_init()
初始化上下文。EVP_PKEY_CTX_set_ec_paramgen_curve_nid
)。EVP_PKEY_paramgen
生成/完成参数,为您提供EVP_PKEY
。EVP_PKEY_CTX
,并使用上一步中的参数EVP_PKEY
进行初始化。EVP_PKEY_keygen_init()
初始化密钥。EVP_PKEY_keygen()
生成/确定密钥。有什么方法可以简化这个过程?例如,我可以只初始化一个键,调用该键上的paramgen函数,然后调用EVP_PKEY_keygen()
吗?根据我的经验,这就是RSA密钥生成的工作方式(您实际上只完成了以上最后两个步骤,而中间发生了第三步)。
documentation指出了这一点,这似乎表明第二个上下文/密钥对是不必要的:
在调用EVP_PKEY_keygen_init()或EVP_PKEY_paramgen_init()算法之后,可以执行特定的控制操作来为该操作设置任何适当的参数。
如果使用相同参数执行多个操作,则可以在同一上下文中多次调用函数EVP_PKEY_keygen()和EVP_PKEY_paramgen()。
也许我误会了,但似乎是在说您可以在调用EVP_PKEY_keygen_init()
之后调用参数设置函数,而不是使用paramgen
函数。
答案 0 :(得分:1)
单独的参数生成阶段实际上是针对Diffie-Hellman之类的算法的,这是必要的。对于EC,您几乎总是使用“标准”参数集(即众所周知的曲线)。因此,OpenSSL允许您对此进行快捷操作,并且仅在您已经知道要使用哪些参数的情况下才进行密钥生成。对于EVP_PKEY_CTX_set_ec_paramgen_curve_nid()
宏,可以通过参数生成或键生成选项将其明确记录为可以使用:
https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_CTX_set_ec_paramgen_curve_nid.html
EVP_PKEY_CTX_set_ec_paramgen_curve_nid()设置EC参数的EC曲线 生成到B。对于EC参数生成,必须调用此宏 或由于没有默认曲线而发生错误。 在以下情况下,也可以调用此函数来显式设置曲线 生成EC密钥。
因此,使用P-256曲线(NID_X9_62_prime256v1)生成密钥的代码可能如下所示:
#include <openssl/evp.h>
#include <openssl/ec.h>
int main(void) {
EVP_PKEY_CTX *ctx;
EVP_PKEY *pkey = NULL;
int ret = 1;
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
if (ctx == NULL)
goto err;
if (EVP_PKEY_keygen_init(ctx) <= 0)
goto err;
if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, NID_X9_62_prime256v1) <= 0)
goto err;
/* Generate key */
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
goto err;
printf("Success!\n");
ret = 0;
err:
EVP_PKEY_CTX_free(ctx);
return ret;
}
这仅需要一个EVP_PKEY
和一个EVP_PKEY_CTX
。