es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Parámetros/clave pública ECDSA

No puedo verificar una firma ECDSA con openssl: tengo la firma, la hash SHA256 de los datos, el nombre de la curva EC y un elemento que la documentación llama clave pública.

Si verifico esta clave pública con openssl, creo que tengo una estructura ecparam:

unsigned char parameters[] = { 0x03, 0x5d, 0x30, 0x6b, 0x47, 0x48,... (copié esos datos al archivo param)
$ openssl ecparam -check -name secp256r1 -in parameters
usando el nombre de curva prime256v1 en lugar de secp256r1
verificando los parámetros de la curva elíptica: ok
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----

Así que creo que esta es una estructura de ecparameters comprimidos.

Estoy tratando de verificar la firma a partir de esos datos, pero aunque puedo adquirir los datos de la firma, no puedo generar una clave a partir de los parámetros.

unsigned char parameters[] = { 0x03, 0x5d, 0x30, 0x6b, 0x47, 0x48...
unsigned char signature[] = { 0x30, 0x45, 0x02, 0x20, 0x77, 0x30...

ECDSA_SIG* derSignature = d2i_ECDSA_SIG(&derSignature, 
    &signaturePtr, sizeof(signature));
EC_KEY*    key1 = d2i_EC_PUBKEY(NULL, &parametersPtr, sizeof(parameters));
EC_KEY*    key2 = d2i_ECParameters(NULL, &parametersPtr, sizeof(parameters));

Mientras que derSignature es un puntero válido, key1 y key2 son nulos. No he encontrado una buena documentación sobre esto, pero sé que también se necesita el nombre de la curva para reconstruir la clave, así que primero creé una estructura de clave asociada con la curva, y luego traté de rellenar la estructura usando los parámetros, pero aún no funciona.

key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

key = d2i_EC_PUBKEY(&key, &parametersPtr, sizeof(parameters));

(También probé esto, mismo resultado)
key = d2i_EC_PUBKEY(&key, &parametersPtr, sizeof(parameters));
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que puede haber algo de confusión con los tipos de datos y las conversiones en el código. A continuación, se presentan algunos consejos para verificar una firma ECDSA con OpenSSL en función de la información proporcionada:

    • El nombre de la curva EC es secp256r1 (o prime256v1, que OpenSSL utiliza indistintamente).
    • La clave pública se codifica utilizando el formato comprimido, que ocupa 33 bytes (1 byte para el signo de la coordenada y y 32 bytes para la coordenada x). Esto es diferente de los parámetros EC, que describen la curva y sus parámetros de manera más general.
    • Para reconstruir la clave pública a partir de su forma comprimida, puede utilizar la función EC_POINT_oct2point de OpenSSL. Asegúrese de establecer el parámetro de forma en POINT_CONVERSION_COMPRESSED y use el nombre de la curva (no los parámetros) para especificar la curva.
    • Una vez que tenga la clave pública como un objeto EC_POINT, puede crear un objeto EC_KEY y establecer su clave pública en el EC_POINT utilizando la función EC_KEY_set_public_key.
    • Por último, puede utilizar la función ECDSA_do_verify para verificar la firma utilizando el hash de los datos y la clave pública reconstruida.

    Aquí hay un ejemplo de un fragmento de código (suponiendo que signature, hash y pub_key son matrices de bytes que contienen la firma, el hash de datos y la clave pública comprimida, respectivamente):

    “`c++
    EC_KEY* key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    EC_GROUP* group = EC_KEY_get0_group(key);

    // Reconstruir clave pública a partir de su forma comprimida
    EC_POINT* point = EC_POINT_new(group);
    EC_POINT_oct2point(group, point, pub_key, 33, NULL);
    EC_KEY_set_public_key(key, point);
    EC_POINT_free(point);

    // Verificar firma
    int result = ECDSA_do_verify(hash, 32, signature, sizeof(signature), key);
    if (result != 1) {
    // la verificación falló
    }


    Tenga en cuenta que se ha omitido el control de errores y la gestión de memoria por brevedad. También es posible utilizar la función `d2i_EC_PUBKEY` para convertir la clave pública comprimida en un objeto `EC_KEY` directamente, pero debe asegurarse de establecer el nombre de la curva antes de hacerlo: ```c++ EC_KEY* key = EC_KEY_new(); // Establecer nombre de la curva EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); EC_KEY_set_group(key, group); // Convertir clave pública comprimida en objeto EC_KEY key = d2i_EC_PUBKEY(&key, &pub_key, 33); EC_GROUP_free(group); // ... continuar con la verificación como antes

Comments are closed.