OpenSSL

密码学和SSL/TLS工具包

EVP_KEYMGMT-DHX

名称

EVP_PKEY-DH、EVP_PKEY-DHX、EVP_KEYMGMT-DH、EVP_KEYMGMT-DHX - EVP_PKEY DH和DHX密钥类型及算法支持

描述

对于DH FFC密钥协商,可以使用两类域参数:“安全”域参数,与批准的命名安全素数组相关联,以及一类“FIPS186-type”域参数。FIPS186-type域参数仅应用于与无法升级以使用批准的安全素数组的现有应用程序向后兼容。

有关FFC密钥的更多信息,请参阅EVP_PKEY-FFC(7)

DH密钥类型使用PKCS#3格式,保存pg,但不保存q值。DHX密钥类型使用X9.42格式,保存q的值,这必须用于FIPS186-4。如果需要密钥验证,用户应了解与FIPS186-4样式参数相关的细微差别,如“DH密钥验证”中所述。

DH和DHX域参数

除了所有FFC密钥类型都应支持的通用FCC参数(请参阅EVP_PKEY-FFC(7)中的“FFC参数”)之外,DHXDH密钥类型实现还支持以下内容

"group" (OSSL_PKEY_PARAM_GROUP_NAME) <UTF8字符串>

设置或获取一个字符串,将DHDHX命名安全素数组与pqg的已知值相关联。

OpenSSL的默认和FIPS提供程序可以使用以下值:“ffdhe2048”、“ffdhe3072”、“ffdhe4096”、“ffdhe6144”、“ffdhe8192”、“modp_2048”、“modp_3072”、“modp_4096”、“modp_6144”、“modp_8192”。

OpenSSL的默认提供程序还可以使用以下附加值:“modp_1536”、“dh_1024_160”、“dh_2048_224”、“dh_2048_256”。

DH/DHX命名组可以轻松验证,因为参数是众所周知的。对于仅传输pg的协议,还可以检索q的值。

DH和DHX附加参数

"encoded-pub-key" (OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY) <八位字节字符串>

用于获取和设置TLS协议密钥交换消息中使用的DH公钥的编码。请参阅EVP_PKEY_set1_encoded_public_key()和EVP_PKEY_get1_encoded_public_key()。

DH附加域参数

"safeprime-generator" (OSSL_PKEY_PARAM_DH_GENERATOR) <整数>

用于使用旧的安全素数生成器代码生成DH安全素数。默认值为2。如果需要域参数验证,建议改为使用命名安全素数组。

FIPS不允许随机生成的安全素数,因此为OpenSSL FIPS提供程序设置此值将改为根据p的大小选择命名安全素数组。

DH和DHX域参数/密钥生成参数

除了所有FFC密钥类型都应支持的通用FFC密钥生成参数(请参阅EVP_PKEY-FFC(7)中的“FFC密钥生成参数”)之外,DHDHX密钥类型实现还支持以下内容

"type" (OSSL_PKEY_PARAM_FFC_TYPE) <UTF8字符串>

设置参数生成的类型。对于DH,有效值为

"fips186_4"
"default"
"fips186_2"

这些在EVP_PKEY-FFC(7)中的“FFC密钥生成参数”中进行了描述

"group"

这指定将使用“pbits”类型选择命名安全素数名称。

"generator"

安全素数生成器。请参阅上面的“safeprime-generator”类型。这仅对DH密钥有效。

"pbits" (OSSL_PKEY_PARAM_FFC_PBITS) <无符号整数>

设置素数'p'的大小(以位为单位)。

对于“fips186_4”,这必须为2048。对于“fips186_2”,这必须为1024。对于“group”,这可以是2048、3072、4096、6144或8192中的任何一个。

"priv_len" (OSSL_PKEY_PARAM_DH_PRIV_LEN) <整数>

一个可选值,用于设置生成的私钥的最大长度。如果未设置此值,则使用默认值,即BN_num_bits(q)的最大值。可以将其设置为的最小值为2 * s。其中s是密钥的安全强度,对于密钥大小为2048、3072、4096、6144和8192,其值为112、128、152、176和200。

DH密钥验证

对于不是命名组的DHX,FIPS186-4标准指定用于FFC参数生成的也需要用于参数验证。这意味着可能需要为验证目的存储seedpcountergindexhindex的可选FFC域参数值。对于DHXseedpcounter可以存储在ASN1数据中(但gindexhindex不能存储)。建议改为使用命名安全素数组。

对于DH密钥,EVP_PKEY_param_check(3)的行为如下:OpenSSL FIPS提供程序测试参数是否为批准的安全素数组,或者FFC参数是否符合SP800-56Ar3域参数有效性的保证中定义的FIPS186-4。OpenSSL默认提供程序使用更简单的检查,允许出于向后兼容性目的没有q值。

对于DH密钥,EVP_PKEY_param_check_quick(3)等效于EVP_PKEY_param_check(3)

对于DH密钥,EVP_PKEY_public_check(3)符合SP800-56Ar3FFC完整公钥验证

对于DH密钥,EVP_PKEY_public_check_quick(3)在DH密钥为批准的命名安全素数组时符合SP800-56Ar3FFC部分公钥验证,否则与EVP_PKEY_public_check(3)相同。

对于DH密钥,EVP_PKEY_private_check(3)测试私钥是否在根据SP800-56Ar3的正确范围内。OpenSSL FIPS提供程序要求设置q的值(请注意,这对于命名安全素数组是设置的)。为了向后兼容,OpenSSL默认提供程序仅要求设置p

对于DH密钥,EVP_PKEY_pairwise_check(3)符合SP800-56Ar3所有者对成对一致性的保证

示例

可以通过调用以下方法获取EVP_PKEY上下文

EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL);

可以通过调用以下方法生成具有命名安全素数组的DH密钥

int priv_len = 2 * 112;
OSSL_PARAM params[3];
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL);

params[0] = OSSL_PARAM_construct_utf8_string("group", "ffdhe2048", 0);
/* "priv_len" is optional */
params[1] = OSSL_PARAM_construct_int("priv_len", &priv_len);
params[2] = OSSL_PARAM_construct_end();

EVP_PKEY_keygen_init(pctx);
EVP_PKEY_CTX_set_params(pctx, params);
EVP_PKEY_generate(pctx, &pkey);
...
EVP_PKEY_free(pkey);
EVP_PKEY_CTX_free(pctx);

可以通过调用以下方法根据FIPS186-4生成DHX域参数

int gindex = 2;
unsigned int pbits = 2048;
unsigned int qbits = 256;
OSSL_PARAM params[6];
EVP_PKEY *param_key = NULL;
EVP_PKEY_CTX *pctx = NULL;

pctx = EVP_PKEY_CTX_new_from_name(NULL, "DHX", NULL);
EVP_PKEY_paramgen_init(pctx);

params[0] = OSSL_PARAM_construct_uint("pbits", &pbits);
params[1] = OSSL_PARAM_construct_uint("qbits", &qbits);
params[2] = OSSL_PARAM_construct_int("gindex", &gindex);
params[3] = OSSL_PARAM_construct_utf8_string("type", "fips186_4", 0);
params[4] = OSSL_PARAM_construct_utf8_string("digest", "SHA256", 0);
params[5] = OSSL_PARAM_construct_end();
EVP_PKEY_CTX_set_params(pctx, params);

EVP_PKEY_generate(pctx, &param_key);

EVP_PKEY_print_params(bio_out, param_key, 0, NULL);
...
EVP_PKEY_free(param_key);
EVP_PKEY_CTX_free(pctx);

可以通过调用以下方法使用域参数生成DH密钥

EVP_PKEY *key = NULL;
EVP_PKEY_CTX *gctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL);

EVP_PKEY_keygen_init(gctx);
EVP_PKEY_generate(gctx, &key);
EVP_PKEY_print_private(bio_out, key, 0, NULL);
...
EVP_PKEY_free(key);
EVP_PKEY_CTX_free(gctx);

要验证从PEMDER数据解码的FIPS186-4 DHX域参数,可能需要将生成期间使用的附加值设置为密钥。

EVP_PKEY_todata()、OSSL_PARAM_merge()和EVP_PKEY_fromdata()可用于在实际验证之前将这些参数添加到原始密钥或域参数中。在生产代码中,应检查返回值。

EVP_PKEY *received_domp = ...; /* parameters received and decoded */
unsigned char *seed = ...;     /* and additional parameters received */
size_t seedlen = ...;          /* by other means, required */
int gindex = ...;              /* for the validation */
int pcounter = ...;
int hindex = ...;
OSSL_PARAM extra_params[4];
OSSL_PARAM *domain_params = NULL;
OSSL_PARAM *merged_params = NULL;
EVP_PKEY_CTX *ctx = NULL, *validate_ctx = NULL;
EVP_PKEY *complete_domp = NULL;

EVP_PKEY_todata(received_domp, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
                &domain_params);
extra_params[0] = OSSL_PARAM_construct_octet_string("seed", seed, seedlen);
/*
 * NOTE: For unverifiable g use "hindex" instead of "gindex"
 * extra_params[1] = OSSL_PARAM_construct_int("hindex", &hindex);
 */
extra_params[1] = OSSL_PARAM_construct_int("gindex", &gindex);
extra_params[2] = OSSL_PARAM_construct_int("pcounter", &pcounter);
extra_params[3] = OSSL_PARAM_construct_end();
merged_params = OSSL_PARAM_merge(domain_params, extra_params);

ctx = EVP_PKEY_CTX_new_from_name(NULL, "DHX", NULL);
EVP_PKEY_fromdata_init(ctx);
EVP_PKEY_fromdata(ctx, &complete_domp, OSSL_KEYMGMT_SELECT_ALL,
                  merged_params);

validate_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, complete_domp, NULL);
if (EVP_PKEY_param_check(validate_ctx) > 0)
    /* validation_passed(); */
else
    /* validation_failed(); */

OSSL_PARAM_free(domain_params);
OSSL_PARAM_free(merged_params);
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_CTX_free(validate_ctx);
EVP_PKEY_free(complete_domp);

符合

RFC 7919(TLS ffdhe命名安全素数组)
RFC 3526(IKE modp命名安全素数组)
RFC 5114(“dh_1024_160”、“dh_2048_224”和“dh_2048_256”的其他DH命名组)。

SP800-56Ar3的以下部分

5.5.1.1 FFC域参数选择/生成
附录D:FFC安全素数组

FIPS186-4的以下部分

A.1.1.2 使用批准的哈希函数生成可能的素数p和q。
A.2.3 生成规范生成器g。
A.2.1 生成器g的不可验证生成。

另请参阅

EVP_PKEY-FFC(7)EVP_KEYEXCH-DH(7) EVP_PKEY(3)provider-keymgmt(7)EVP_KEYMGMT(3)OSSL_PROVIDER-default(7)OSSL_PROVIDER-FIPS(7)

版权所有 2020-2021 OpenSSL 项目作者。保留所有权利。

根据 Apache 许可证 2.0(“许可证”)获得许可。除非符合许可证,否则您不得使用此文件。您可以在源代码分发版中的LICENSE文件中或https://www.openssl.org/source/license.html中获取副本。