PortuguêsWebhooksAssinatura HMAC

Verificação da assinatura

Toda requisição de webhook chega com:

  • X-Infi-Timestamp: unix timestamp em segundos.
  • X-Infi-Signature: sha256=<hex>, onde <hex> é o HMAC-SHA256 calculado sobre a concatenação "{timestamp}.{corpo bruto}" usando o segredo do webhook.

Algoritmo

  1. Capture o corpo bruto da requisição (bytes, antes de qualquer parsing JSON).
  2. Capture os headers X-Infi-Timestamp e X-Infi-Signature.
  3. Concatene: payload = "{timestamp}.{rawBody}".
  4. Compute expected = HMAC-SHA256(WEBHOOK_SECRET, payload) e codifique em hex.
  5. Compare "sha256=" + expected com o cabeçalho recebido em tempo constante.
Use o corpo bruto, não JSON reserializado

A assinatura é sobre os bytes exatos enviados. Reserializar o JSON do seu lado pode mudar ordem de chaves ou espaçamento e quebrar a verificação. Configure seu framework para preservar o body bruto (ex.: em Express use express.raw({ type: 'application/json' })).

Onde obter o `WEBHOOK_SECRET`

O segredo é entregue junto com sua API key, pelo canal seguro combinado com a INFI (e-mail criptografado ou painel). Não exponha em código-fonte público nem em logs — armazene como variável de ambiente.

Mitigação de replay

Recomendado: rejeite webhooks com X-Infi-Timestamp muito antigo (ex.: > 5 minutos). Isso protege contra replay de webhooks legítimos capturados em trânsito.

Exemplos

# Validação shell — geralmente delega para a linguagem da aplicação.
# Conceito:
#   payload="${TIMESTAMP}.${RAW_BODY}"
#   expected=$(echo -n "$payload" | openssl dgst -sha256 -hmac "$INFI_WEBHOOK_SECRET" | awk '{print $2}')
#   [[ "sha256=$expected" == "$X_INFI_SIGNATURE" ]]