c openssl pki elliptic-curve diffie-hellman

¿Cómo se accede a la clave pública, clave privada y parámetros de ECDH sin procesar dentro de la estructura EVP_PKEY de OpenSSL?



pki elliptic-curve (1)

Estoy utilizando la biblioteca c de OpenSSL para generar un par de claves Diffie-Hellman (ECDH) de curva elíptica, siguiendo el primer ejemplo de código here . Pasa por alto el intercambio real de claves públicas con esta línea:

peerkey = get_peerkey(pkey);

La variable pkey y el valor de retorno son de tipo EVP * . pkey contiene la clave pública, la clave privada y los parámetros generados anteriormente, y el valor de retorno solo contiene la clave pública del igual. Así que esto plantea tres preguntas:

  1. ¿Cómo podría get_peerkey() extraer realmente solo la clave pública de pkey para enviarla al interlocutor?
  2. ¿Cómo extraería el código la clave privada y los parámetros de pKey para almacenarlos para su uso posterior después del intercambio de claves?
  3. ¿Cómo podría get_peerkey() generar una nueva estructura EVP_PKEY partir de la clave pública sin EVP_PKEY del igual?

He visto las funciones de OpenSSL EVP_PKEY_print_public() , EVP_PKEY_print_private() y EVP_PKEY_print_params() pero estas son para generar resultados legibles por el ser humano. Y no he encontrado ningún equivalente para convertir una clave pública legible por humanos nuevamente en una estructura EVP_PKEY .


Para responder a mi propia pregunta, hay una ruta diferente para la clave privada y la clave pública.

Para serializar la clave pública:

  1. Pase el EVP_PKEY a EVP_PKEY_get1_EC_KEY () para obtener un EC_KEY.
  2. Pase el EC_KEY a EC_KEY_get0_public_key () para obtener un EC_POINT.
  3. Pase el EC_POINT a EC_POINT_point2oct () para obtener octetos, que son solo caracteres sin signo *.

Para deserializar la clave pública:

  1. Pase los octetos a EC_POINT_oct2point () para obtener un EC_POINT.
  2. Pase el EC_POINT a EC_KEY_set_public_key () para obtener un EC_KEY.
  3. Pase el EC_KEY a EVP_PKEY_set1_EC_KEY para obtener un EVP_KEY.

Para serializar la clave privada:

  1. Pase el EVP_PKEY a EVP_PKEY_get1_EC_KEY () para obtener un EC_KEY.
  2. Pase el EC_KEY a EC_KEY_get0_private_key () para obtener un BIGNUM.
  3. Pase el BIGNUM a BN_bn2mpi () para obtener un mpi, que es un formato escrito en caracteres sin firmar *.

Para deserializar la clave privada:

  1. Pase el mpi a BN_mpi2bn () para obtener un BIGNUM.
  2. Pase el BIGNUM a EC_KEY_set_private_key () para obtener un EC_KEY.
  3. Pase el EC_KEY a EVP_PKEY_set1_EC_KEY para obtener un EVP_KEY.

También es posible convertir BIGNUM a hexadecimal, decimal o "bin", aunque creo que mpi utiliza el menor número de bytes.