You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenSSL 3.0中使用EVP接口实现ECDH密钥交换?

OpenSSL 3.0下EVP接口实现ECDH公钥导出与密钥派生

在OpenSSL 3.0中,EC_KEY_get0_public_key这类EC_KEY*系列API已被弃用,只能使用EVP接口。我的需求是将公钥导出到缓冲区,对其计算MAC,接收端验证MAC后再用该密钥进行DH密钥交换。

我已经成功生成了包含EC密钥的EVP_PKEY对象,但无法提取公钥(原始字节)和群组名称,没法重建ECDH密钥交换。

void generateAndExport() {
  /* params have been set */
  EVP_PKEY_CTX *keygen_ctx;
  EVP_PKEY *ec_key;
  size_t pubkey_size;

  if (!(keygen_ctx = EVP_PKEY_CTX_new(ec_params, NULL)))
    return -1;

  if (!EVP_PKEY_keygen_init(keygen_ctx))
    return -1;

  if (!EVP_PKEY_keygen(keygen_ctx, &ec_key))
    return -1;

  pubkey_size = 0;
  /* Query the buffer size */
  if (!EVP_PKEY_get_octet_string_param(
          ec_key, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pubkey_size))
    return -1;

  /* Allocate the buffer for the public key */
  if (!(ec_pub = calloc(1, pubkey_size)))
    return -1;

  /* Get the public key */
  if (!EVP_PKEY_get_octet_string_param(ec_key,
                                       OSSL_PKEY_PARAM_PUB_KEY, ec_pub,
                                       pubkey_size, &pubkey_size))
    return -1;

  /* calculate a MAC over the public key */

cleanup:
  EVP_PKEY_CTX_free(keygen_ctx);
  EVP_PKEY_free(ec_key);
  return 0;
}

编辑: 以下是实现需求的正确代码。如果有人需要,我附上用于恢复公钥并派生共享密钥的代码:

void deriveSharedSecret(EVP_PKEY *priv,
                        unsigned char *pkey,
                        size_t pkey_len,
                        unsigned char *group_name,
                        unsigned char **shared_key,
                        size_t *shared_key_len) {
  EVP_PKEY_CTX *derive_ctx = NULL;
  EVP_PKEY *peer_key = NULL;

  CHECK(pkey && (pkey_len > 0));

  CHECK(!(peer_key = EVP_PKEY_new_raw_public_key(
          EVP_PKEY_EC,
          NULL,
          pkey,
          pkey_len)));
  CHECK(derive_ctx = EVP_PKEY_CTX_new(priv, NULL));
  CHECK(EVP_PKEY_derive_init(derive_ctx));
  CHECK(EVP_PKEY_CTX_set_group_name(derive_ctx, group_name));
  CHECK(EVP_PKEY_derive_set_peer(derive_ctx, peer_key));

  /* Query buffer size for shared secret */
  *shared_key_len = 0;
  CHECK(EVP_PKEY_derive(derive_ctx, NULL, shared_key_len));

  if (!(*shared_key = calloc(1, *shared_key_len)))
    return -1;
  CHECK(EVP_PKEY_derive(derive_ctx, *shared_key, shared_key_len));

  EVP_PKEY_free(peer_key);
  EVP_PKEY_CTX_free(derive_ctx);
  return 0;
}

另外,获取群组名称的代码如下:

unsigned char groupname[MAX_GROUP_NAME_SIZE];
size_t groupname_len;

CHECK(EVP_PKEY_get_octet_string_param(
      ec_key,
      OSSL_PKEY_PARAM_GROUP_NAME,
      groupname,
      0,
      &groupname_len));

内容的提问来源于stack exchange,提问作者vibhav950

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:13:15