从OpenSSL 1.1升级到3.0.8:OSSL_PARAM_BLD及DH使用咨询
OpenSSL 3.0.8 DH升级相关问题解答
1. OSSL_PARAM_BLD 所需头文件
要使用OSSL_PARAM_BLD结构体,只需包含公开头文件:
#include <openssl/params.h>
OpenSSL 3.0将参数构建相关的类型、函数统一放在这个头文件中,无需包含内部的types.h或crypto/param_build.c(后者是实现文件,不应被直接包含)。
2. 替代 DH_new() 的DH实现示例
OpenSSL 3.0废弃了直接操作DH*结构体的接口,改用基于EVP_PKEY的密钥交换框架,以下是完整的DH密钥交换示例:
#include <openssl/evp.h> #include <openssl/params.h> #include <stdio.h> #include <string.h> int main() { // 初始化OpenSSL库(3.0版本建议调用) OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); // 1. 生成DH参数(2048位) EVP_PKEY_CTX *param_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); if (!param_ctx) { fprintf(stderr, "Failed to create param context\n"); return 1; } if (EVP_PKEY_paramgen_init(param_ctx) <= 0 || EVP_PKEY_CTX_set_dh_paramgen_prime_len(param_ctx, 2048) <= 0) { fprintf(stderr, "Failed to set DH param specs\n"); EVP_PKEY_CTX_free(param_ctx); return 1; } EVP_PKEY *dh_params = NULL; if (EVP_PKEY_paramgen(param_ctx, &dh_params) <= 0) { fprintf(stderr, "Failed to generate DH params\n"); EVP_PKEY_CTX_free(param_ctx); return 1; } EVP_PKEY_CTX_free(param_ctx); // 2. 生成甲方密钥对 EVP_PKEY_CTX *key_ctx = EVP_PKEY_CTX_new(dh_params, NULL); if (!key_ctx) { fprintf(stderr, "Failed to create key context\n"); EVP_PKEY_free(dh_params); return 1; } if (EVP_PKEY_keygen_init(key_ctx) <= 0) { fprintf(stderr, "Failed to init key gen\n"); EVP_PKEY_CTX_free(key_ctx); EVP_PKEY_free(dh_params); return 1; } EVP_PKEY *alice_key = NULL; if (EVP_PKEY_keygen(key_ctx, &alice_key) <= 0) { fprintf(stderr, "Failed to generate Alice's key\n"); EVP_PKEY_CTX_free(key_ctx); EVP_PKEY_free(dh_params); return 1; } EVP_PKEY_CTX_free(key_ctx); // 3. 生成乙方密钥对 key_ctx = EVP_PKEY_CTX_new(dh_params, NULL); if (!key_ctx) { fprintf(stderr, "Failed to create key context\n"); goto cleanup; } if (EVP_PKEY_keygen_init(key_ctx) <= 0) { fprintf(stderr, "Failed to init key gen\n"); goto cleanup; } EVP_PKEY *bob_key = NULL; if (EVP_PKEY_keygen(key_ctx, &bob_key) <= 0) { fprintf(stderr, "Failed to generate Bob's key\n"); goto cleanup; } EVP_PKEY_CTX_free(key_ctx); // 4. 甲方计算共享密钥 unsigned char alice_shared[256]; size_t alice_shared_len = sizeof(alice_shared); key_ctx = EVP_PKEY_CTX_new(alice_key, NULL); if (!key_ctx || EVP_PKEY_derive_init(key_ctx) <= 0 || EVP_PKEY_derive_set_peer(key_ctx, bob_key) <= 0 || EVP_PKEY_derive(key_ctx, alice_shared, &alice_shared_len) <= 0) { fprintf(stderr, "Alice failed to derive shared key\n"); goto cleanup; } EVP_PKEY_CTX_free(key_ctx); // 5. 乙方计算共享密钥 unsigned char bob_shared[256]; size_t bob_shared_len = sizeof(bob_shared); key_ctx = EVP_PKEY_CTX_new(bob_key, NULL); if (!key_ctx || EVP_PKEY_derive_init(key_ctx) <= 0 || EVP_PKEY_derive_set_peer(key_ctx, alice_key) <= 0 || EVP_PKEY_derive(key_ctx, bob_shared, &bob_shared_len) <= 0) { fprintf(stderr, "Bob failed to derive shared key\n"); goto cleanup; } EVP_PKEY_CTX_free(key_ctx); // 验证共享密钥一致性 if (alice_shared_len == bob_shared_len && memcmp(alice_shared, bob_shared, alice_shared_len) == 0) { printf("Shared keys match successfully!\n"); } else { printf("Shared keys do NOT match!\n"); } cleanup: EVP_PKEY_CTX_free(key_ctx); EVP_PKEY_free(alice_key); EVP_PKEY_free(bob_key); EVP_PKEY_free(dh_params); return 0; }
示例说明
- 用
EVP_PKEY统一管理密钥,替代原有的DH*结构体 - 通过
EVP_PKEY_CTX配置密钥生成、参数生成、密钥派生的上下文 - 密钥派生流程使用
EVP_PKEY_derive系列函数,兼容多种密钥交换算法
内容的提问来源于stack exchange,提问作者Sank
相关产品推荐
相关产品推荐

