OpenSSL ECDH устанавливает открытый ключ партнера в C - PullRequest
1 голос
/ 09 мая 2019

Я пытаюсь интегрировать ECDH с использованием OpenSSL в мой C-SDK (который мы будем называть клиентом), который работает на Ubuntu и нуждался в некоторой помощи относительно того, как установить одноранговый узел (сервер)открытый ключ на стороне клиента и, в конечном счете, генерация общего секрета.

Некоторые детали:

  1. Я успешно генерирую открытый ключ, а также могу сгенерировать общий секрет на стороне сервера, которыйимеет встроенный микроконтроллер, использующий библиотеку mbedTLS.
  2. Открытый ключ, который я получаю от сервера, имеет вид uint8_t массива 32 bytes.
  3. Я хочу сейчасиспользовать ECDH OpenSSL для генерации открытого ключа для сервера и общего секрета на стороне клиента.

Я нашел пример кода на вики-сайте OpenSSL , который приведен ниже:

#include <openssl/evp.h>
#include <openssl/ec.h>


unsigned char *ecdh(size_t *secret_len)
{
    EVP_PKEY_CTX *pctx, *kctx;
    EVP_PKEY_CTX *ctx;
    unsigned char *secret;
    EVP_PKEY *pkey = NULL, *peerkey, *params = NULL;
    /* NB: assumes pkey, peerkey have been already set up */

    /* Create the context for parameter generation */
    if(NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) handleErrors();

    /* Initialise the parameter generation */
    if(1 != EVP_PKEY_paramgen_init(pctx)) handleErrors();

    /* We're going to use the ANSI X9.62 Prime 256v1 curve */
    if(1 != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1)) handleErrors();

    /* Create the parameter object params */
    if (!EVP_PKEY_paramgen(pctx, &params)) handleErrors();

    /* Create the context for the key generation */
    if(NULL == (kctx = EVP_PKEY_CTX_new(params, NULL))) handleErrors();

    /* Generate the key */
    if(1 != EVP_PKEY_keygen_init(kctx)) handleErrors();
    if (1 != EVP_PKEY_keygen(kctx, &pkey)) handleErrors();

    /* Get the peer's public key, and provide the peer with our public key -
     * how this is done will be specific to your circumstances */
    peerkey = get_peerkey(pkey);

    /* Create the context for the shared secret derivation */
    if(NULL == (ctx = EVP_PKEY_CTX_new(pkey, NULL))) handleErrors();

    /* Initialise */
    if(1 != EVP_PKEY_derive_init(ctx)) handleErrors();

    /* Provide the peer public key */
    if(1 != EVP_PKEY_derive_set_peer(ctx, peerkey)) handleErrors();

    /* Determine buffer length for shared secret */
    if(1 != EVP_PKEY_derive(ctx, NULL, secret_len)) handleErrors();

    /* Create the buffer */
    if(NULL == (secret = OPENSSL_malloc(*secret_len))) handleErrors();

    /* Derive the shared secret */
    if(1 != (EVP_PKEY_derive(ctx, secret, secret_len))) handleErrors();

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(peerkey);
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(kctx);
    EVP_PKEY_free(params);
    EVP_PKEY_CTX_free(pctx);

    /* Never use a derived secret directly. Typically it is passed
     * through some hash function to produce a key */
    return secret;
}

В примере есть строка peerkey = get_peerkey(pkey);, в которой он устанавливает peerkey и, в основном, оставляет его на усмотрение пользователя для реализации этой функции.Я полагаю, что было бы просто, если бы я использовал OpenSSL и на стороне сервера.

Мой вопрос:

Ссылаясь на приведенный выше код и помня, что я получаюПубличный ключ сервера в виде массива uint8_t, как мне установить контекст EVP_PKEY *peerkey, чтобы он содержал открытый ключ сервера?

Если есть другая криптографическая библиотека в C, которую я могу использовать в Ubuntuтогда, пожалуйста, предложите!

Очень ценю любую помощь.

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...