1

我正在编写一个通过连接到 Google 服务器的 TCP 套接字发送消息来参与 TLS 1.2 握手的客户端。我正在使用 ECDH 密钥交换方法。

我使用此代码生成了客户端密钥对,现在我想将 ClientKeyExchange 发送到包含公钥的服务器。为此,我首先需要将 EVP_PKEY 中包含的密钥传输到缓冲区中。我已经对服务器 peerkey 进行了相反的转换,但我现在还没有弄清楚该怎么做。

我的代码是:

void get_buffer(EVP_PKEY * pkey, unsigned char * client_pub_key, int pkeyLen) {

   EC_KEY *tempEcKey = NULL;

   tempEcKey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

   if(0 == (EVP_PKEY_set1_EC_KEY(pkey, tempEcKey))){
      handleErrors();
   }

   const EC_GROUP * group = EC_KEY_get0_group(tempEcKey);
   point_conversion_form_t form = EC_GROUP_get_point_conversion_form(group);

   //write in the buffer
   pkeyLen = EC_KEY_key2buf(tempEcKey, form, *client_pub_key, NULL);
   if(pkeyLen == 0){
      handleErrors();
   } 
}

该代码在调用时会导致分段错误EVP_PKEY_set1_EC_KEY(pkey, tempEcKey)

我究竟做错了什么?

我也查看了该EVP_PKEY_get_raw_public_key()功能,但它也不起作用。文档

4

2 回答 2

0

您需要从 EVP_PKEY 获取 EC_KEY 而不是EC_KEY_new_by_curve_nameEVP_PKEY_set1_EC_KEY使用EVP_PKEY_get0_EC_KEY

EC_KEY_key2buf为您分配一个缓冲区并且没有使用预分配的缓冲区,这个分配的缓冲区必须使用OPENSSL_free释放。

void get_buffer(EVP_PKEY * pkey, unsigned char ** client_pub_key, int *pkeyLen) {
    EC_KEY *tempEcKey = NULL;

    tempEcKey = EVP_PKEY_get0_EC_KEY(pkey);
    if(tempEcKey == NULL) {
        handleErrors("Getting EC_KEY from EVP_PKEY");
        return;
    }

    const EC_GROUP * group = EC_KEY_get0_group(tempEcKey);
    point_conversion_form_t form = EC_GROUP_get_point_conversion_form(group);

    *pkeyLen = EC_KEY_key2buf(tempEcKey, form, client_pub_key, NULL);
    if(*pkeyLen == 0){
       handleErrors("Creating buffer from key");
       return;
    } 
}
于 2019-11-08T00:18:05.467 回答
0

我遇到了同样的问题,这对我有用:

std::size_t len = 32;
uint8_t* pubkey = new uint8_t[len];

EVP_PKEY_get_raw_public_key(pkey, pubkey, &len);
于 2020-03-25T08:37:32.020 回答