Formatear JSON
Formatear, validar y plegar JSON.
Desarrollo
Firmas HMAC para verificar webhooks.
El caso de uso cotidiano son los webhooks.
Cuando un servicio externo envía una petición a tu servidor — una confirmación de pago, un cambio de estado — de entrada no sabes si viene realmente de ese servicio, porque tu URL la puede conocer cualquiera.
HMAC lo resuelve: el emisor calcula una firma a partir del contenido del mensaje y de un secreto compartido, y la envía junto al mensaje. Tú calculas la misma firma con el mismo secreto y comparas.
Si coinciden, el mensaje viene de alguien que conoce el secreto y no se ha alterado.
El segundo caso son las peticiones firmadas a una API, donde se firman conjuntamente el método, la ruta, una marca de tiempo y el cuerpo.
Un matiz importante: HMAC no es cifrado. El mensaje sigue siendo legible; HMAC solo garantiza el origen y la integridad.
Y tampoco es una firma electrónica en sentido jurídico: ambas partes conocen el mismo secreto, así que cualquiera de las dos puede generarla. Para valor legal en España se usan la firma electrónica cualificada y los certificados reconocidos, que funcionan con criptografía asimétrica.
En la verificación se cometen siempre los mismos errores.
Compara las firmas en tiempo constante. Una comparación de cadenas normal se detiene en el primer carácter distinto, y del tiempo que tarda se puede deducir la firma correcta poco a poco. Casi todos los lenguajes tienen una función específica para esto.
Firma el cuerpo en bruto de la petición, no el objeto ya interpretado y vuelto a serializar. Un espacio distinto o un orden diferente de las claves JSON cambia la firma.
Comprueba la marca de tiempo si el proveedor la envía y rechaza las peticiones antiguas. De lo contrario, un atacante puede reenviar más tarde un mensaje válido.
Fíjate en la codificación exacta: hexadecimal o Base64, mayúsculas o minúsculas, con prefijo o sin él. Cada proveedor lo hace a su manera, y esa es la causa más frecuente de una firma que "casi" coincide.
Y trata el secreto como una contraseña: ni en el código, ni en el repositorio, sino en la configuración del entorno.
La elección es más sencilla de lo que parece.
| Algoritmo | Valoración |
|---|---|
| HMAC-SHA256 | la opción estándar |
| HMAC-SHA512 | también válida |
| HMAC-SHA1 | obsoleto, solo sistemas heredados |
| HMAC-MD5 | no utilizar |
SHA-256 es la opción por defecto razonable y la que usan la mayoría de proveedores.
Es curioso que HMAC en sí resiste bastante bien las debilidades del algoritmo de resumen subyacente, por lo que HMAC-SHA1 no se considera roto de inmediato. Aun así, no hay motivo para elegirlo en algo nuevo.
La longitud de la clave debería ser al menos la del resumen, es decir 32 bytes aleatorios con SHA-256.
Y la clave debe ser aleatoria de verdad. Un secreto inventado a mano es el eslabón más débil de toda la cadena.
Esta herramienta calcula íntegramente en tu navegador y la clave no sale de tu equipo. Aun así: para secretos de producción usa tu propio entorno, no una interfaz web.
Para comprobar que un mensaje, normalmente un webhook, es auténtico y no se ha modificado.
No. El mensaje sigue siendo legible; solo garantiza origen e integridad.
Porque del tiempo de una comparación normal se puede deducir la firma correcta.
Suele ser porque se ha vuelto a serializar el cuerpo, o por la codificación: hex frente a Base64.
HMAC-SHA256 como estándar. No uses MD5.
No, el cálculo es local. Aun así, usa tu propio entorno para secretos de producción.