Generador de HMAC y verificador de firmas

Calcula HMAC-SHA-1, SHA-256, SHA-384 y SHA-512 a partir de un mensaje y una clave, e identifica de cuál procede una firma dada.

Mensaje
HMAC-SHA-1
HMAC-SHA-256
HMAC-SHA-384
HMAC-SHA-512

Introduzca una clave para calcular las firmas.

Qué hace esta herramienta

HMAC convierte un mensaje y un secreto compartido en una firma corta. Quien tenga el mismo secreto puede recalcularla y ver si el mensaje llegó sin cambios y si vino de alguien que también conoce el secreto. Esta herramienta calcula las cuatro variantes habituales a la vez y, dada una firma que le enviaron, le dice cuál la produjo.

Ese segundo sentido suele ser el motivo por el que la gente llega aquí. Un webhook falla la verificación, y la pregunta real no es «¿es válida esta firma?» sino «¿cuál de las varias cosas plausibles estoy haciendo distinto del remitente?».

La clave es donde esto se tuerce

HMAC firma bytes con bytes. El mensaje suele ser evidente —el cuerpo de la petición en bruto— pero la clave casi nunca lo es, porque un secreto llega como cadena y una cadena no es bytes hasta que usted decide cómo leerla:

a3f2  ->  61 33 66 32   4 bytes   como texto
a3f2  ->  a3 f2         2 bytes   como hex

Ambas lecturas son legítimas, ambas producen una firma perfectamente bien formada, y las dos firmas no tienen nada en común. Nada le avisa: no hay error, no hay queja de longitud, solo un valor que no coincide con el que calculó el remitente. Por eso aquí la codificación de la clave es una elección visible y no una suposición: cuando una firma no coincide, esto es lo primero que hay que cambiar.

Como guía aproximada: un secreto con un prefijo tipo whsec_ o una tirada de letras y dígitos en mayúsculas y minúsculas suele ir como texto; una cadena de exactamente 32 o 64 caracteres que solo usa 0-9 y a-f suele ser hexadecimal; y una que termina en = es casi con seguridad Base64. Pero consulte la documentación del remitente en vez de la forma, porque la forma no es prueba.

El mensaje tiene que ser los bytes exactos

La otra mitad de una discrepancia es el mensaje. HMAC está definido sobre bytes, así que cualquier cosa que cambie los bytes cambia la firma por completo: no hay nota parcial ni casi acierto.

  • Volver a serializar el JSON. Analizar un cuerpo y volver a convertirlo en cadena puede reordenar claves, cambiar espacios o normalizar números. Firme y verifique el cuerpo en bruto que recibió, nunca una copia que ha ido y vuelto.
  • Un salto de línea final. Algunas herramientas lo añaden al guardar el cuerpo en un archivo; es un byte, y lo cambia todo.
  • La codificación de caracteres. Un cuerpo con texto no ASCII tiene que leerse con la misma codificación en ambos lados: en la práctica, UTF-8.
  • Compresión o middleware. Si algo delante de su manejador descomprime o reescribe el cuerpo, verifique antes de que eso ocurra, no después.

Además, muchos proveedores no firman solo el cuerpo. Stripe firma una marca de tiempo y el cuerpo unidos por un punto; AWS firma una petición canónica construida a partir del método, la ruta, las cabeceras y un hash de la carga. Si la verificación falla contra el cuerpo simple, es probable que la cadena firmada no sea el cuerpo simple: eso está documentado del lado del remitente y conviene leerlo antes de seguir depurando.

Por qué aquí se ofrece SHA-1 y en la herramienta de hash no

La herramienta de hash marca SHA-1 como roto. Esta lista HMAC-SHA-1 sin advertencia, y es deliberado, no un descuido.

SHA-1 es inservible para firmas y certificados porque se pueden construir colisiones: dos documentos distintos pueden hacerse compartir un resumen. HMAC no depende de esa propiedad. Su seguridad descansa en la clave secreta, y la construcción —resumir el mensaje dos veces, con la clave mezclada en ambas— aguanta incluso cuando el hash subyacente es débil frente a colisiones. HMAC-SHA-1 sigue siendo sólido y es lo que usan OAuth 1.0a y la firma antigua de AWS, así que una herramienta que se negara a calcularlo sería simplemente menos útil sin ser más segura.

Para algo nuevo, SHA-256 es la opción sensata. Los resúmenes más largos no son significativamente más fuertes aquí —el techo de seguridad es la clave, no la longitud del resumen—, así que SHA-384 y SHA-512 solo merecen la pena cuando algo con lo que debe interoperar los pide.

Comparar firmas con seguridad

Esta página compara con una comparación de cadenas normal, y aquí está bien: usted tiene la clave, así que no hay nada que filtrar. En un servidor que verifica una petición entrante, no está bien. Una comparación normal se detiene en el primer byte distinto, así que el tiempo que tarda revela qué parte de una conjetura era correcta, y un atacante que pueda enviar muchas peticiones puede recuperar una firma válida byte a byte.

Use la comparación en tiempo constante que ofrezca su plataforma —crypto.timingSafeEqual en Node, hmac.compare_digest en Python, hash_equals en PHP— sobre los bytes en bruto y no sobre cadenas hexadecimales. Junto a eso, compare contra una firma que haya calculado usted y no confíe en un algoritmo nombrado en la petición, y rechace un mensaje cuya marca de tiempo esté lejos de ahora para que una firma válida antigua no pueda reproducirse.

HMAC no es un hash, ni una firma

Aquí se confunden tres cosas, y la diferencia importa para lo que se puede afirmar después:

  • Un hash toma un mensaje y produce un resumen. Cualquiera puede calcularlo, así que demuestra que el mensaje no cambió por accidente, no que venga de alguien en concreto.
  • Un HMAC toma un mensaje y un secreto compartido. Las dos partes tienen la misma clave, así que demuestra que el remitente conocía el secreto. No puede demostrar cuál de las dos lo envió, porque cualquiera pudo producirlo.
  • Una firma usa una clave privada que solo tiene el remitente y una clave pública con la que cualquiera puede verificar. Eso es lo que da el no repudio: el remitente no puede negarlo después.

Así que HMAC es la herramienta adecuada entre dos sistemas que ya comparten un secreto —webhooks, API internas, tokens de sesión— y la equivocada cuando hay que demostrar a un tercero quién envió algo. Fíjese también en que autentica pero no oculta: el mensaje viaja en claro, y HMAC no dice nada sobre confidencialidad.

Preguntas frecuentes

Mi firma no coincide. ¿Qué compruebo primero?
La codificación de la clave y luego los bytes del mensaje. Un secreto que parece hexadecimal a menudo se quiere como hexadecimal y no como texto, y ambos producen firmas completamente distintas sin error en ningún caso. Después, asegúrese de firmar el cuerpo en bruto tal como se recibió y no una copia re-serializada.
¿Por qué se ofrece SHA-1 si la herramienta de hash dice que está roto?
Porque HMAC no depende de la resistencia a colisiones, que es la propiedad que SHA-1 perdió. Su seguridad viene de la clave. HMAC-SHA-1 sigue siendo sólido y en uso por OAuth 1.0a y la firma antigua de AWS, aunque SHA-256 es el valor por defecto adecuado para algo nuevo.
¿Un resumen más largo es más seguro?
No de forma significativa. La fuerza de un HMAC está limitada por el secreto, no por la longitud del resumen, así que SHA-512 no es cuatro veces mejor que SHA-256. Elija el que espere la otra parte.
¿Qué diferencia hay entre HMAC y una firma digital?
HMAC usa un secreto que ambas partes conocen, así que demuestra que el remitente conocía el secreto pero no cuál de los dos lo envió. Una firma digital usa una clave privada que solo tiene el remitente, de modo que un tercero puede verificarla y el remitente no puede negarla. Si necesita esa última propiedad, HMAC no es la herramienta.
¿Debo comparar firmas con ===?
En un servidor, no. Una comparación normal vuelve en cuanto los bytes difieren, y ese tiempo filtra qué parte de una firma adivinada era correcta. Use la comparación en tiempo constante de su plataforma sobre los bytes en bruto. En esta página da igual, porque usted ya tiene la clave.
¿Se envía mi clave a algún sitio?
No. Todo se calcula en su navegador con la Web Crypto API; el mensaje y la clave nunca salen de su dispositivo.