MiServe DevTools

Tus pegatinas

Fija aquí tus herramientas. Se guardan en este navegador.

Generador de HMAC

Firma un mensaje con una clave secreta usando HMAC-SHA256 u otro hash, y comprueba una firma que hayas recibido.

HMAC (hex)
HMAC (Base64)

Funciona en tu navegador con WebAssembly. Nada de lo que pegas se sube.

Acerca de esta herramienta

Qué demuestra un HMAC

HMAC (RFC 2104) combina un mensaje con una clave secreta mediante una función hash y devuelve una etiqueta corta. Quien tenga la misma clave puede volver a calcular la etiqueta. Si las dos etiquetas son iguales, el mensaje no se modificó por el camino (integridad) y lo generó alguien que conoce la clave (autenticidad).

Un hash simple no puede hacerlo, porque quien altere el mensaje también puede recalcular su hash. Un HMAC no oculta el mensaje, así que no es cifrado. Y como ambas partes tienen la misma clave, no puede demostrar cuál de las dos escribió el mensaje. Para eso hace falta una firma digital con una clave privada.

Firmas de webhooks

HMAC aparece a menudo en los webhooks. El proveedor firma el cuerpo de la petición con un secreto que comparte contigo y envía la etiqueta en una cabecera, y tu servidor calcula el mismo HMAC antes de fiarse de la petición. GitHub envía X-Hub-Signature-256: sha256=… en hex, Shopify envía X-Shopify-Hmac-SHA256 en Base64, y Stripe firma el timestamp, un punto y el cuerpo, y envía el resultado como v1=… dentro de Stripe-Signature.

Firma los bytes en bruto del cuerpo exactamente como llegaron. Si un framework interpreta el JSON y tú lo vuelves a serializar, cambian los espacios y el orden de las propiedades, y el HMAC deja de coincidir. Cuando aquí una firma no coincida, revisa primero la codificación de la clave (texto, hex o Base64) y después si hay un salto de línea al final del mensaje.

Por qué un servidor compara en tiempo constante

Una comparación de cadenas normal se detiene en el primer carácter distinto. En un servidor, eso hace que la respuesta sea un poco más rápida cuando los primeros bytes de una firma falsificada son incorrectos y un poco más lenta cuando son correctos, y un atacante capaz de medirlo puede reconstruir una etiqueta válida byte a byte. Una comparación en tiempo constante lee todos los bytes, sea cual sea el resultado. Usa la función que ofrece tu plataforma: crypto.timingSafeEqual en Node.js, hmac.Equal en Go, hmac.compare_digest en Python, hash_equals en PHP.

El campo de comparación de esta página funciona igual: decodifica ambos valores a bytes y los lee todos. En una pestaña del navegador que ya tiene los dos valores no hay ningún tiempo que ocultar, así que aquí solo te dice si tu propio código generó la etiqueta correcta.

Cómo funciona

La etiqueta la calcula el paquete crypto/hmac de Go compilado a WebAssembly y ejecutado en un hilo en segundo plano de tu navegador. El mensaje se toma como UTF-8, sin añadir ni recortar nada. Solo cambia una cosa: un cuadro de texto del navegador guarda cada salto de línea como un único avance de línea, así que un mensaje que llegó con finales de línea CRLF se firma aquí con LF. La clave se toma como texto UTF-8, o se decodifica desde hex o Base64 si así lo indicas. Ninguno de los dos se envía a ninguna parte. Aun así, es mejor no poner un secreto de producción en una página web: usa una clave de prueba cuando puedas.

Preguntas

¿Por qué mi HMAC es distinto del que calcula mi servidor?

Las causas habituales son leer la clave con la codificación equivocada (una clave hex o Base64 tratada como texto), un salto de línea al final o finales de línea distintos en el mensaje, un cuerpo que se interpretó y se volvió a serializar, o un algoritmo de hash distinto. Comprueba también si la otra parte muestra el resultado en hex o en Base64.

¿HMAC es lo mismo que calcular el hash de la clave seguida del mensaje?

No. Con SHA-256, SHA-512, SHA-1 o MD5, el hash de la clave más el mensaje se puede extender: quien vea el hash puede añadir datos y calcular un hash válido sin conocer la clave. HMAC aplica el hash dos veces con dos claves derivadas, lo que cierra ese agujero.

¿Qué longitud debe tener una clave HMAC?

Usa una clave aleatoria al menos tan larga como la salida del hash: 32 bytes para SHA-256, 64 bytes para SHA-512. Una clave más larga aporta poco, y una clave más larga que el tamaño de bloque del hash se reduce primero calculando su hash. Una clave corta o fácil de adivinar se puede encontrar probando candidatas contra un mensaje y una etiqueta conocidos.

¿HMAC-SHA1 y HMAC-MD5 están rotos?

Los ataques de colisión que rompieron SHA-1 y MD5 como hashes simples no se traducen en una falsificación práctica de sus HMAC. Todavía aparecen en protocolos antiguos, pero para cualquier cosa nueva elige HMAC-SHA256 o algo más robusto.

Más herramientas de Hash