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 類型」網域參數。FIPS186 類型的網域參數應僅用於與無法升級為使用已核准安全質數群組的現有應用程式向後相容。

請參閱 EVP_PKEY-FFC(7) 以取得有關 FFC 金鑰的更多資訊。

DH 金鑰類型使用 PKCS#3 格式,該格式儲存 pg,但不儲存 q 值。DHX 金鑰類型使用 X9.42 格式,該格式儲存 q 的值,且必須用於 FIPS186-4。如果需要金鑰驗證,使用者應注意與 FIPS186-4 風格參數相關的細微差別,如 「DH 金鑰驗證」 中所述。

DH 和 DHX 網域參數

除了所有 FFC 金鑰類型都應支援的常見 FCC 參數外(請參閱 EVP_PKEY-FFC(7) 中的「FFC 參數」),DHXDH 金鑰類型實作還支援下列參數:

「群組」(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 其他參數

「編碼公鑰」(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) <整數>

使用舊的 safeprime 產生器程式碼,用於 DH 產生 safeprime。預設值為 2。建議改用已命名 safeprime 群組,如果需要網域參數驗證。

FIPS 不允許隨機產生的 safeprime,因此為 OpenSSL FIPS 提供者設定這個值,將會根據 p 的大小,選擇一個已命名 safeprime 群組。

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」類型,選擇已命名的 safeprime 名稱。

"generator"

一個 safeprime 產生器。請參閱上方的「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,s 的值分別為 112、128、152、176 和 200。

DH 金鑰驗證

對於非已命名群組的 DHX,FIPS186-4 標準指定用於 FFC 參數產生的值,也需要用於參數驗證。這表示需要儲存 種子pcountergindexhindex 的選用 FFC 網域參數值,以進行驗證。對於 DHX種子pcounter 可以儲存在 ASN1 資料中(但 gindexhindex 無法儲存)。建議改用已命名 safeprime 群組。

對於 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-56Ar3 FFC 完整公開金鑰驗證

對於 DH 金鑰,EVP_PKEY_public_check_quick(3) 在 DH 金鑰為已核准的命名安全質數群組時,符合 SP800-56Ar3 FFC 部分公開金鑰驗證,否則與 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)

Copyright 2020-2021 The OpenSSL Project Authors。保留所有權利。

根據 Apache 授權條款 2.0(「授權條款」)授權。您只能在遵守授權條款的情況下使用此檔案。您可以在原始程式碼中的 LICENSE 檔案中取得一份副本,或至 https://www.openssl.org/source/license.html 取得。