2012-09-22 18 views

Respuesta

5

... ¿cuál es la diferencia entre EVP y HMAC

EVP_* funciones son una interfaz de alto nivel. HMAC_*, AES_* y amigos son primitivos de nivel inferior. Puede trabajar con cualquiera de ellos, pero se recomienda que trabaje con las funciones EVP_*. Las rutinas HMAC_* están basadas en software y no usan hardware.

Las funciones EVP_* le permitirán intercambiar fácilmente diferentes valores hash y el código permanece esencialmente igual. Y aprovechará la aceleración de hardware, como AES-NI para un AES-CMAC, si está disponible.

Aquí hay un ejemplo de OpenSSL basado en https://www.openssl.org/docs/crypto/EVP_DigestInit.html.

EVP_MD_CTX* mdctx = NULL; 
const EVP_MD* md = NULL; 

unsigned char md_value[EVP_MAX_MD_SIZE]; 
int md_len = 0; 

char message[] = "Now is the time for all good men to " 
    "come to the aide of their country\n"; 

OpenSSL_add_all_digests(); 

md = EVP_get_digestbyname("SHA1"); 
mdctx = EVP_MD_CTX_create(); 

if(!EVP_DigestInit_ex(mdctx, md, NULL)) 
    handleError(); 

if(!EVP_DigestUpdate(mdctx, message, strlen(message))) 
    handleError(); 

if(!EVP_DigestFinal_ex(mdctx, md_value, &md_len)) 
    handleError(); 

if(!EVP_MD_CTX_destroy(mdctx)) 
    handleError(); 

printf("Digest is: "); 
for(int i = 0; i < md_len; i++) 
    printf("%02x", md_value[i]); 
printf("\n"); 

Ahora, y HMAC es ligeramente diferente a un Hash. El HMAC es un hash con clave, mientras que el hash no está codificado. También puede usar las funciones EVP_* para HMAC'ing. A continuación es de la página wiki de OpenSSL EVP Signing and Verifying:

EVP_MD_CTX* mdctx = NULL; 
const EVP_MD* md = NULL; 
EVP_PKEY *pkey = NULL; 

unsigned char md_value[EVP_MAX_MD_SIZE]; 
int md_len = 0; 

char message[] = "Now is the time for all good men to " 
    "come to the aide of their country\n"; 

OpenSSL_add_all_digests(); 

if(!(mdctx = EVP_MD_CTX_create())) 
    handleError(); 

if(!(md = EVP_get_digestbyname("SHA1"))) 
    handleError(); 

if(!(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, "password", strlen("password")))) 
    handleError(); 

if(1 != EVP_DigestSignInit(mdctx, NULL, md, NULL, pkey)) 
    handleError(); 

/* Call update with the message */ 
if(1 != EVP_DigestSignUpdate(mdctx, message, strlen(message))) 
    handleError(); 

if(1 != EVP_DigestSignFinal(mdctx, md_value, &md_len)) 
    handleError(); 

printf("HMAC is: "); 
for(int i = 0; i < md_len; i++) 
    printf("%02x", md_value[i]); 
printf("\n"); 

La interfaz de bajo nivel sería similar a:

EVP_MD_CTX* mdctx = NULL; 
const EVP_MD* md = NULL; 

unsigned char md_value[EVP_MAX_MD_SIZE]; 
int md_len = 0; 

char message[] = "Now is the time for all good men to " 
"come to the aide of their country\n"; 

OpenSSL_add_all_digests(); 

md = EVP_get_digestbyname("SHA1"); 
mdctx = EVP_MD_CTX_create(); 

if(!HMAC_Init_ex(mdctx, key, sizeof(key), md, NULL)) 
    handleError(); 

if(!HMAC_Update(mdctx, message, strlen(message))) 
    handleError(); 

if(!HMAC_Final(mdctx, md_value, &md_len)) 
    handleError(); 

if(!HMAC_CTX_cleanup(mdctx)) 
    handleError(); 

printf("HMAC is: "); 
for(int i = 0; i < md_len; i++) 
    printf("%02x", md_value[i]); 
printf("\n"); 
+0

Hay un problema importante con su código. '' 'key''' no es' '' unsigned char''' array, es '' 'EVP_PKEY'''. Además, hay algunos errores tipográficos. – jcoffland

+1

He buscado cómo crear EVP_PKEY (más en http://wiki.openssl.org/index.php/EVP_Key_and_Parameter_Generation) –

+0

¿Cómo usar esto para calcular CMAC? – user489152

1

Es necesario utilizar EVP_PKEY_new_mac_key función con el fin de obtener la estructura llave correcta para HMAC. Y no olvides liberarlo con EVP_PKEY_free.