2008-10-28 7 views
10

Estoy intentando configurar una prueba básica de hash HMAC-SHA-256 pero estoy teniendo problemas con la configuración del motor. Idealmente, me gustaría configurar solo el algoritmo HMAC-SHA, pero hasta ahora no he tenido el caso general en el que cargar todos los algoritmos para trabajar. Actualmente obtengo seg_segmentos en la fila donde intento establecer los resúmenes por defecto.Descripción de la inicialización del motor en OpenSSL

Además, regularmente soy Java, así que no dudes en señalar cualquier error en el código.

#include <openssl/hmac.h> 
#include <openssl/evp.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main() { 
    unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 
    unsigned char* data = (unsigned char*) "4869205468657265"; 
    unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"; 
    unsigned char* result; 
    HMAC_CTX* ctx; 
    ENGINE* e; 

    ENGINE_load_builtin_engines(); 
    ENGINE_register_all_complete(); 
    ENGINE_set_default_digests(e); 

    HMAC_CTX_init(ctx); 
    HMAC_Init_ex(ctx, key, 40, EVP_sha256(), e); 
    result = HMAC(NULL, NULL, 40, data, 16, NULL, NULL); 
    HMAC_CTX_cleanup(ctx); 

    ENGINE_finish(e); 
    ENGINE_free(e); 

    if (strcmp((char*) result, (char*) expected) == 0) { 
    printf("Test ok\n"); 
    } else { 
    printf("Got %s instead of %s\n", result, expected); 
    } 
} 

EDIT: El programa ha evolucionado a lo siguiente, pero todavía estoy en violación de segmento HMAC_Init_ex:

unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; 
unsigned char* data = (unsigned char*) "4869205468657265"; 
unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"; 
unsigned char* result; 
unsigned int result_len = 64; 
HMAC_CTX ctx; 
ENGINE* e; 

result = (unsigned char*) malloc(sizeof(char) * result_len); 
e = (ENGINE*) ENGINE_new(); 

ENGINE_load_builtin_engines(); 
ENGINE_register_all_complete(); 
ENGINE_set_default_digests(e); 

HMAC_CTX_init(&ctx); 
HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), e); 
HMAC_Update(&ctx, data, 40); 
HMAC_Final(&ctx, result, &result_len); 
HMAC_CTX_cleanup(&ctx); 

ENGINE_finish(e); 
ENGINE_free(e); 

Respuesta

13

El problema con su sugerencia original es, como dijo Martin, que necesita inicializar el MOTOR. El problema con su código editado era que estaba haciendo ENGINE_new, que le proporciona un MOTOR completamente nuevo, que luego debe proporcionar con métodos de cifrado, métodos de resumen, etc. De hecho, para lo que desea (y qué casi todo el mundo quiere), ignorar por completo todo el material del MOTOR es la elección correcta.

Algunos problemas subsidiarios:

  • sus cuerdas eran hexagonal, pero que necesitaban un \ x por carácter para conseguir realmente ese byte hexadecimal en esa posición en la cadena, que sospecho era lo que quería.
  • intentaba hash 40 bytes de "datos", que no fue tan largo (efecto real: terminaría en parte hash su cadena de resultados)
  • su resultado esperado fue (por lo que puedo decir) incorrecto
  • imprimiría caracteres aleatorios en el terminal, ya que la función HMAC producirá 32 bytes de datos binarios aleatorios, no material imprimible.

El siguiente código compila, funciona y pasa la prueba. Es un poco diferente al código de ejemplo que has encontrado (ya que todavía utiliza la HMAC_ individuo * funciones - útil si desea hacer su parte hash utilizando HMAC_Update bits):

#include <openssl/engine.h> 
#include <openssl/hmac.h> 
#include <openssl/evp.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 


int main(void) 
{ 
     unsigned char* key = (unsigned char*) "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; 
     unsigned char* data = (unsigned char*) "\x48\x69\x20\x54\x68\x65\x72\x65"; 
     unsigned char* expected = (unsigned char*) "\x49\x2c\xe0\x20\xfe\x25\x34\xa5\x78\x9d\xc3\x84\x88\x06\xc7\x8f\x4f\x67\x11\x39\x7f\x08\xe7\xe7\xa1\x2c\xa5\xa4\x48\x3c\x8a\xa6"; 
     unsigned char* result; 
     unsigned int result_len = 32; 
     int i; 
     HMAC_CTX ctx; 

     result = (unsigned char*) malloc(sizeof(char) * result_len); 

     ENGINE_load_builtin_engines(); 
     ENGINE_register_all_complete(); 

     HMAC_CTX_init(&ctx); 
     HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), NULL); 
     HMAC_Update(&ctx, data, 8); 
     HMAC_Final(&ctx, result, &result_len); 
     HMAC_CTX_cleanup(&ctx); 

     for (i=0; i!=result_len; i++) 
     { 
       if (expected[i]!=result[i]) 
       { 
         printf("Got %02X instead of %02X at byte %d!\n", result[i], expected[i], i); 
         break; 
       } 
     } 
     if (i==result_len) 
     { 
       printf("Test ok!\n"); 
     } 
     return 0; 
} 

Por supuesto, no lo hace responda su pregunta original sobre cómo inicializar MOTORES, pero realmente no hay una respuesta correcta sin tener más contexto, que el contexto resulta no ser relevante en su situación ...

0

Parece como si nada es la asignación de un motor, por lo que el primer uso de e es segfaulting. Creo que primero debe llamar al ENGINE *ENGINE_new(void).

(Tenga en cuenta que he utilizado OpenSSL, pero no he utilizado las funciones ENGINE antes.)

actualización: No soy muy feliz con mi propia respuesta (tuve que a garabatear té, antes). Así que mis observa además son:

  1. que he tenido un poco de un vistazo a la (larga) man page para los ENGINE funciones, y no estoy seguro de que llamar ENGINE_new es suficiente.

  2. No noté que las llamadas a las funciones HMAC_CTX_* tomaban un puntero no inicializado, en lugar de un puntero a una estructura asignada. HMAC_CTX_init intentará escribir en la memoria apuntada por su parámetro ctx, que segmentará. Es necesario declarar y utilizar ctx así:

    HMAC_CTX ctx; 
    HMAC_CTX_init(&ctx); 
    HMAC_Init_ex(&ctx, key, 40, EVP_sha256(), e); 
    ... 
    

    De esa manera usted está asignando la estructura en la pila, y después de pasar un puntero a ella.

  3. La función HMAC no toma un puntero a una CTX en absoluto, así que aparte de almacenamiento global o local de subprocesos, no estoy seguro de lo que es la conexión a la CTX está. Creo que puede eludir eso llamando al HMAC_Update una o más veces, seguido de HMAC_Final para obtener el resultado. Que había necesidad de asignar espacio para que el resultado, así que algo como lo siguiente trabajaría para ello:

    unsigned int len; 
    HMAC_Final(&ctx, result, &len); 
    
+0

Gracias por la sugerencia Martin, lo he intentado fuera pero todavía estoy atascado. Tengo curiosidad sobre el comentario de ENGINE acerca de que no lo has usado. ¿Es posible usar OpenSSL sin un motor? – Fylke

1

bien, resulta que usted no tiene que utilizar un motor pero me entendió mal exactamente cómo no usar un motor explícito. También malentendí cómo formatear correctamente los vectores de prueba. Al final, miré hmactest.c, que hace todo lo que quiero hacer, simplemente no entendí el código.

La solución final a lo que yo estaba tratando de hacer es así:

int main() { 
    unsigned char* key = (unsigned char*) "Jefe"; 
    unsigned char* data = (unsigned char*) "what do ya want for nothing?"; 
    unsigned char* expected = (unsigned char*) "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"; 
    unsigned char* result; 
    unsigned int result_len = 32; 
    int i; 
    static char res_hexstring[32]; 

    result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL); 
    for (i = 0; i < result_len; i++) { 
    sprintf(&(res_hexstring[i * 2]), "%02x", result[i]); 
    } 

    if (strcmp((char*) res_hexstring, (char*) expected) == 0) { 
    printf("Test ok, result length %d\n", result_len); 
    } else { 
    printf("Got %s instead of %s\n", res_hexstring, expected); 
    } 
} 

Pero puesto que estaba preguntando acerca de algo completamente diferente, estoy seguro acerca de qué hacer con la pregunta original. Sugerencias?

+0

NULL. Nota: pasar un valor NULL para que md use la matriz estática no es seguro para subprocesos. https://www.openssl.org/docs/man1.0.2/crypto/hmac.html – codenamezero

Cuestiones relacionadas