HMAC
En criptografía, un HMAC (a veces expandido como código de autenticación de mensajes con clave hash o código de autenticación de mensajes basado en hash) es un tipo específico de código de autenticación de mensajes (MAC) que implica una función hash criptográfica y una clave criptográfica secreta. Al igual que con cualquier MAC, se puede usar para verificar simultáneamente la integridad de los datos y la autenticidad de un mensaje.
HMAC puede proporcionar autenticación mediante un secreto compartido en lugar de utilizar firmas digitales con criptografía asimétrica. Equilibra la necesidad de una infraestructura de clave pública compleja al delegar el intercambio de claves a las partes que se comunican, que son responsables de establecer y utilizar un canal confiable para acordar la clave antes de la comunicación.
Detalles
Cualquier función hash criptográfica, como SHA-2 o SHA-3, puede usarse en el cálculo de un HMAC; el algoritmo MAC resultante se denomina HMAC-X, donde X es la función hash utilizada (por ejemplo, HMAC-SHA256 o HMAC-SHA3-512). La fortaleza criptográfica del HMAC depende de la fortaleza criptográfica de la función hash subyacente, el tamaño de su salida hash y el tamaño y la calidad de la clave.
HMAC utiliza dos pases de cálculo hash. Antes de pasar, la clave secreta se usa para derivar dos claves: interna y externa. Luego, el primer paso del algoritmo hash produce un hash interno derivado del mensaje y la clave interna. El segundo paso produce el código HMAC final derivado del resultado hash interno y la clave externa. Por lo tanto, el algoritmo proporciona una mejor inmunidad contra los ataques de extensión de longitud.
Una función hash iterativa (que usa la construcción Merkle-Damgård) divide un mensaje en bloques de un tamaño fijo y los itera con una función de compresión. Por ejemplo, SHA-256 opera en bloques de 512 bits. El tamaño de la salida de HMAC es el mismo que el de la función hash subyacente (por ejemplo, 256 y 512 bits en el caso de SHA-256 y SHA3-512, respectivamente), aunque se puede truncar si se desea.
HMAC no cifra el mensaje. En su lugar, el mensaje (cifrado o no) debe enviarse junto con el hash HMAC. Las partes con la clave secreta volverán a codificar el mensaje y, si es auténtico, los algoritmos hash recibidos y calculados coincidirán.
La definición y el análisis de la construcción HMAC se publicaron por primera vez en 1996 en un artículo de Mihir Bellare, Ran Canetti y Hugo Krawczyk, y también escribieron RFC 2104 en 1997. El artículo de 1996 también definió una variante anidada llamada NMAC (MAC anidado). FIPS PUB 198 generaliza y estandariza el uso de HMAC. HMAC se usa dentro de los protocolos IPsec, SSH y TLS y para JSON Web Tokens.
Definición
Esta definición está tomada de RFC 2104:
dónde
- H es una función de hash criptográfica.
- m es el mensaje para ser autenticado.
- K es la clave secreta.
- K' es una clave de tamaño bloque derivada de la clave secreta, K; ya sea acolchando a la derecha con 0s hasta el tamaño de bloque, o por reducir a menos o igual al tamaño de bloque primero y después padding a la derecha con ceros.
- denota concatenación.
- ⊕ denota bitwise exclusiva o (XOR).
- Operaciones es el relleno exterior de tamaño bloque, que consiste en bytes repetidos valorados 0x5c.
- ipad es el relleno interior de tamaño bloque, que consiste en bytes repetidos valorados 0x36.
Función Hash H | b , bytes
| L , bytes
|
---|---|---|
MD5 | 64 | 16 |
SHA-1 | 64 | 20 |
SHA-224 | 64 | 28 |
SHA-256 | 64 | 32 |
SHA-512/224 | 128 | 28 |
SHA-512/256 | 128 | 32 |
SHA-384 | 128 | 48 |
SHA-512 | 128 | 64 |
SHA3-224 | 144 | 28 |
SHA3-256 | 136 | 32 |
SHA3-384 | 104 | 48 |
SHA3-512 | 72 | 64 |
out = H(in) |
Implementación
El siguiente pseudocódigo demuestra cómo se puede implementar HMAC. El tamaño del bloque es de 512 bits (64 bytes) cuando se usa una de las siguientes funciones hash: SHA-1, MD5, RIPEMD-128.
función hmac es entrada:clave: Bytes // Array of bytesMensaje: Bytes // Array of bytes to be hashedhash: Función // La función hash para usar (por ejemplo, SHA-1)bloque Tamaño: entero // El tamaño de bloque de la función hash (por ejemplo, 64 bytes para SHA-1)Producto Tamaño: entero // El tamaño de salida de la función hash (por ejemplo 20 bytes para SHA-1) // Computar la llave tamaño bloqueblock_sized_key = computeBlockSizedKey(key, hash, blockSize) o_key_pad ← block_sized_key xor [0x5c blockSize] // llave acolchada exteriori_key_pad ← block_sized_key xor [0x36 blockSize] llave acolchada interior retorno hash(o_key_pad ∥ hash(i_key_pad ∥ message) función computador BlockSized Clave es entrada:clave: Bytes // Array of byteshash: Función // La función hash para usar (por ejemplo, SHA-1)bloque Tamaño: entero // El tamaño de bloque de la función hash (por ejemplo, 64 bytes para SHA-1) // Llaves más largas que blockSize son acortados por la piratería si (length(key) entoncesclave = hash(key) // Llaves más cortas que blockSize están acolchados blockSize con ceros a la derecha si (longitud(llamado) entonces retorno Pad(key, blockSize) // Llave con ceros para hacerlo blockSize bytes long retorno clave
Principios de diseño
El diseño de la especificación HMAC estuvo motivado por la existencia de ataques a mecanismos más triviales para combinar una clave con una función hash. Por ejemplo, se podría suponer que se podría lograr la misma seguridad que proporciona HMAC con MAC = H(clave ∥ mensaje). Sin embargo, este método tiene una falla grave: con la mayoría de las funciones hash, es fácil agregar datos al mensaje sin conocer la clave y obtener otra MAC válida ("ataque de extensión de longitud"). La alternativa, agregar la clave usando MAC = H(mensaje ∥ clave), tiene el problema de que un atacante que puede encontrar una colisión en la función hash (sin clave) tiene una colisión en el MAC (ya que dos mensajes m1 y m2 que arrojan el mismo hash proporcionarán la misma condición de inicio para la función hash antes de que la clave adjunta sea codificada, por lo tanto, el hash final será el mismo). Usar MAC = H(clave ∥ mensaje ∥ clave) es mejor, pero varios documentos de seguridad han sugerido vulnerabilidades con este enfoque, incluso cuando se utilizan dos claves diferentes.
No se han encontrado ataques de extensión conocidos contra la especificación HMAC actual que se define como H(key ∥ H(key ∥ mensaje)) porque la aplicación externa de la función hash enmascara el resultado intermedio del hash interno. Los valores de ipad y opad no son críticos para la seguridad del algoritmo, pero se definieron de tal manera que tuvieran una gran distancia de Hamming entre sí y, por lo tanto, el interior y las claves externas tendrán menos bits en común. La reducción de seguridad de HMAC requiere que sean diferentes en al menos un bit.
La función hash de Keccak, que fue seleccionada por NIST como ganadora de la competencia SHA-3, no necesita este enfoque anidado y se puede usar para generar un MAC simplemente anteponiendo la clave al mensaje, tal como está no es susceptible a los ataques de extensión de longitud.
Seguridad
La fortaleza criptográfica del HMAC depende del tamaño de la clave secreta que se utiliza y de la seguridad de la función hash subyacente utilizada. Se ha demostrado que la seguridad de una construcción HMAC está directamente relacionada con las propiedades de seguridad de la función hash utilizada. El ataque más común contra los HMAC es la fuerza bruta para descubrir la clave secreta. Los HMAC se ven sustancialmente menos afectados por las colisiones que sus algoritmos hash subyacentes por sí solos. En particular, Mihir Bellare demostró que HMAC es un PRF bajo el único supuesto de que la función de compresión es un PRF. Por lo tanto, HMAC-MD5 no sufre de las mismas debilidades que se han encontrado en MD5.
RFC 2104 requiere que las "claves de más de B bytes primero se conviertan en hash usando H" lo que conduce a una pseudo-colisión confusa: si la clave es más larga que el tamaño del bloque hash (por ejemplo, 64 bytes para SHA-1), entonces HMAC(k, m)
se calcula como HMAC (H(k), m).
Esta propiedad a veces se plantea como una posible debilidad de HMAC en escenarios de hashing de contraseñas: se ha demostrado que es posible encontrar una cadena ASCII larga y una cadena aleatoria valor cuyo hash será también una cadena ASCII, y ambos valores producirán la misma salida HMAC.
En 2006, Jongsung Kim, Alex Biryukov, Bart Preneel y Seokhie Hong mostraron cómo distinguir HMAC con versiones reducidas de MD5 y SHA-1 o versiones completas de HAVAL, MD4 y SHA-0 de una función aleatoria o HMAC con una función aleatoria. Los distintivos diferenciales permiten a un atacante idear un ataque de falsificación en HMAC. Además, los distintivos diferenciales y rectangulares pueden dar lugar a ataques de segunda preimagen. Con este conocimiento, se puede forjar HMAC con la versión completa de MD4. Estos ataques no contradicen la prueba de seguridad de HMAC, pero brindan información sobre HMAC en función de las funciones hash criptográficas existentes.
En 2009, Xiaoyun Wang et al. presentó un ataque distintivo en HMAC-MD5 sin usar claves relacionadas. Puede distinguir una instanciación de HMAC con MD5 de una instanciación con una función aleatoria con 297 consultas con probabilidad 0,87.
En 2011, se publicó un RFC 6151 informativo para resumir las consideraciones de seguridad en MD5 y HMAC-MD5. Para HMAC-MD5, el RFC resume que, aunque la seguridad de la función hash MD5 en sí está gravemente comprometida, los "ataques actualmente conocidos en HMAC-MD5 no parecen indicar una vulnerabilidad práctica cuando se usan como mensaje. código de autenticación", pero también agrega que "para un nuevo diseño de protocolo, no se debe incluir un conjunto de cifrado con HMAC-MD5".
En mayo de 2011, se publicó RFC 6234 que detalla la teoría abstracta y el código fuente para los HMAC basados en SHA.
Ejemplos
Estos son algunos valores HMAC, suponiendo una codificación ASCII de 8 bits:
HMAC_MD5("key", "El zorro marrón rápido salta sobre el perrito perezoso") = 80070713463e7749b90c2dc24911e275
HMAC_SHA1("key", "El zorro marrón rápido salta sobre el perrito perezoso") = de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
HMAC_SHA256("key", "El zorro marrón rápido salta sobre el perrito perezoso") = f7bc83f430538424b13298e6aaa6fb143ef4d59a14946175997479dbc2d1a3cd8
HMAC_SHA512("key", "El zorro marrón rápido salta sobre el perrito perezoso") = b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec39352250357e
Contenido relacionado
UTF-8
Forma normal de Chomsky
Kilobyte