Um hash comum, como o SHA-256, prova só que dois conteúdos são iguais. Qualquer pessoa calcula o hash de qualquer texto. O HMAC acrescenta um segredo ao cálculo: sem ele, não dá para produzir a assinatura certa, mesmo conhecendo a mensagem.
Como funciona
O HMAC é descrito na RFC 2104, de 1997. O cálculo combina a chave secreta com a mensagem em duas passagens pela função de hash. Com SHA-256, o resultado tem 32 bytes, em geral escritos como 64 caracteres hexadecimais.
Três cuidados evitam a maior parte dos erros:
- HMAC não cifra a mensagem. O conteúdo continua legível. A assinatura prova origem e integridade, não sigilo. O transporte continua em HTTPS.
- Os bytes importam. Um espaço a mais, outra ordem de campos ou outra codificação geram outra assinatura. Calcule sobre o payload exatamente como chegou, antes de converter o JSON em objeto.
- Compare em tempo constante. Uma comparação comum para no primeiro caractere diferente, e essa diferença de tempo pode ajudar um atacante. Use
timingSafeEqualno Node.js ouhmac.compare_digestno Python.
Na API da xFlow
Todo webhook da xFlow traz o header x-webhook-signature no formato sha256= seguido do HMAC-SHA256 do corpo cru, calculado com o segredo do endpoint. Esse segredo aparece uma única vez, quando o endpoint é criado. Pela API, ele vem na resposta 201 de POST /api/v1/webhooks.
O segredo do endpoint não é o segredo da chave de API. Um assina o que a xFlow envia para você; o outro autentica o que você envia para a xFlow.
Exemplo
Para conferir uma assinatura no terminal, com o corpo recebido salvo em arquivo:
# corpo.json = bytes exatos recebidos; SEGREDO = segredo do endpoint
printf 'sha256=%s\n' "$(openssl dgst -sha256 -hmac "$SEGREDO" < corpo.json | awk '{print $NF}')"O resultado precisa ser igual ao valor do header x-webhook-signature. Se não bater, confira se o arquivo guarda o corpo original, sem formatação. O código de validação dentro da aplicação está em webhook Pix, em API Pix em Node.js e em API Pix em Python.
Termos relacionados
- Webhook: o aviso HTTP que chega assinado com HMAC.
- Payload: o conteúdo sobre o qual a assinatura é calculada.
- Idempotência: o outro cuidado ao receber eventos repetidos.