Saltar al contenido

Generador HMAC

Depura firmas de webhooks: pega el cuerpo tal cual, el secreto y la firma que recibiste.

HMAC

¿Qué hace?

Calcula el HMAC (código de autenticación de mensajes basado en hash) de un mensaje con una clave secreta, usando SHA-256, SHA-384, SHA-512 o SHA-1, y lo muestra en hex y Base64. Pega la firma que recibiste y la herramienta te dice si coincide.

Cómo se usa

  1. Pega el cuerpo sin procesar de la petición, byte a byte.
  2. Escribe la clave secreta. Si tu proveedor te la da en hex o Base64, cambia el formato de la clave.
  3. Pega la cabecera de firma que recibiste (sha256=…, t=…,v1=…, hex o Base64) para comprobarla.

Verificar un webhook de GitHub en Node.js

import { createHmac, timingSafeEqual } from "node:crypto";

const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const valid = timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-hub-signature-256"]));

Preguntas frecuentes

›¿Por qué la firma de mi webhook nunca coincide?

Casi siempre porque el cuerpo se modificó antes de calcularla: se analizó y volvió a serializar como JSON, se recortó o se recodificó. El HMAC debe calcularse sobre los bytes exactos tal como llegaron.

›¿Qué formato usan Stripe y GitHub?

GitHub envía X-Hub-Signature-256: sha256=<hex>. Stripe envía Stripe-Signature: t=<timestamp>,v1=<hex>, firmando el texto <timestamp>.<cuerpo>. Pega cualquiera de las dos cabeceras en Firma recibida.

›¿Cómo debo comparar firmas en mi código?

Con una comparación de tiempo constante (crypto.timingSafeEqual en Node.js, hmac.compare_digest en Python) para evitar ataques de temporización.