¿Hay algo diferente en cuanto a la seguridad de estos dos algoritmos de hash? ¿HMAC "fusiona" los datos y la clave de una forma especial que es más consciente de la seguridad?
¿Hay algo diferente en cuanto a la seguridad de estos dos algoritmos de hash? ¿HMAC "fusiona" los datos y la clave de una forma especial que es más consciente de la seguridad?
Sí, HMAC es más complejo que una simple concatenación.
Como ejemplo simplista, si tuviera que concatenar simplemente key + data, entonces "key1" + "data" produce resultados idénticos a "key" + "1data", que es subóptimo. HMAC dará resultados diferentes para cada uno. También hay otros defectos con concatenación simple en muchos casos; vea la respuesta de cpast para uno.
La especificación para HMAC se llama RFC2104 , que debe leer si tiene este nivel de interés.
En resumen, para implementar HMAC, primero debes:
Crea "ipad", que es 0x36
veces repetidas en BLOCKSIZE.
Cree "opad", que es 0x5c
veces repetidas de BLOCKSIZE.
Entonces HMAC se define como:
HASH(Key XOR opad, HASH(Key XOR ipad, text))
o, en detalle desde el RFC,
(Pretexto: La definición de HMAC requiere una función criptográfica hash, que lo denotamos por H, y una clave secreta K. Asumimos que H es un criptográfico Función hash donde los datos se procesan mediante la iteración de una compresión básica Funcionar sobre bloques de datos. Denotamos por B la longitud en bytes de tales bloques.)
(1) append zeros to the end of K to create a B byte string
(e.g., if K is of length 20 bytes and B=64, then K will be
appended with 44 zero bytes 0x00)
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
(1) with ipad
(3) append the stream of data 'text' to the B byte string resulting
from step (2)
(4) apply H to the stream generated in step (3)
(5) XOR (bitwise exclusive-OR) the B byte string computed in
step (1) with opad
(6) append the H result from step (4) to the B byte string
resulting from step (5)
(7) apply H to the stream generated in step (6) and output
the result
En realidad, hay un gran problema con SHA256(key||data)
: SHA-256, junto con SHA-512, SHA-1, MD5 y todos los demás hashes que usan la construcción Merkle – Damgård, son vulnerables a extensión de longitud ataque: dado H(x)
, es muy sencillo encontrar H(x||y)
, incluso si solo conoces la longitud de x
, porque De cómo funciona la construcción.
(Esencialmente, la construcción funciona así: tienes una variable state
que comienza con un valor fijo especificado en el algoritmo. Divides la entrada a la función hash en bloques del tamaño especificado en el algoritmo (rellenando la última bloque si es demasiado corto), y para cada bloque, utiliza el bloque actual y el actual state
para calcular el nuevo state
usando alguna función especial especificada en el algoritmo. El valor de state
después de procesar el último bloque es el valor hash. Con cualquier función que use esta construcción, si tiene la longitud de x
, puede calcular el relleno p
utilizado. Luego, si tiene H(x)
, tiene el estado después de procesar cada bloque de x||p
, lo que significa que puede proceder desde allí para calcular H(x||p||y)
).
Eso significa que un atacante que conoce la longitud de su clave MAC y conoce un valor particular de SHA256(key||data)
puede calcular fácilmente SHA256(key||data||otherdata)
para un determinado otherdata
. Pueden elegir la mayoría de los otros datos, pero incluso si no pudieran, es un error fatal en un esquema MAC si un atacante sin la clave puede forjar cualquier par de datos MAC de otro MAC legítimo pares de datos.
Por cierto, SHA256(data||key)
, aunque no es vulnerable a la extensión de longitud, es vulnerable a colisiones en SHA256
, que también puede producir colisiones en el MAC propuesto, debido a la misma construcción iterada. La anidación de HMAC previene estos y varios otros ataques. Sin embargo, con los hashes que no son Merkle-Damgård, no necesariamente se necesita la construcción HMAC.
Lea otras preguntas en las etiquetas hmac