Gerador de HMAC online

O HMAC é um código calculado a partir de uma mensagem e de uma chave secreta, usado para provar que a mensagem veio de quem tem a chave e não foi alterada, como nas assinaturas de webhooks e de APIs. Esta ferramenta calcula HMAC-SHA256, SHA1, SHA384, SHA512 e MD5 no seu navegador e ainda confere uma assinatura recebida, sem enviar a mensagem nem a chave a nenhum servidor.

Atualizado em · Por Leonardo Gaertner

HMAC
-

Achou um resultado errado ou tem uma sugestão? Avise por e-mail.

Como usar

  1. Digite ou cole a mensagem e a chave secreta.
  2. Escolha o algoritmo (o mais usado é o HMAC-SHA256) e em que formato a chave está: texto, hexadecimal ou Base64.
  3. Copie o resultado em hexadecimal ou Base64.
  4. Para conferir uma assinatura de webhook, cole-a no último campo, com ou sem o prefixo sha256=.

Como funciona

O HMAC, definido na RFC 2104, mistura a chave com a mensagem em duas rodadas de uma função de hash: HMAC(K, m) = H((K xor opad) seguido de H((K xor ipad) seguido de m)). Uma chave maior que o bloco da função (64 bytes para SHA-256, 128 para SHA-512) é reduzida com o próprio hash antes.

O resultado só bate com o do outro lado se os bytes forem exatamente os mesmos. Isso vale para a chave, cujo formato importa (uma chave em Base64 tratada como texto gera outro HMAC), e para a mensagem: use o corpo original da requisição, sem reformatar o JSON e sem espaços ou quebras de linha a mais no fim. O texto é convertido para UTF-8 antes do cálculo.

Colisões conhecidas no MD5 e no SHA-1 não quebram o HMAC da mesma forma, mas para projetos novos a recomendação é usar HMAC-SHA256 ou superior. O HMAC prova autenticidade e integridade, e não esconde a mensagem: ele não é criptografia.

Exemplo (HMAC-SHA256)

Chave: key

Mensagem: The quick brown fox jumps over the lazy dog

HMAC: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

Fonte: RFC 2104: HMAC; RFC 4231: vetores de teste do HMAC com SHA-2

Em código

Para conferir a assinatura HMAC-SHA256 de um webhook, compare o valor recebido com o calculado sobre o corpo original, em tempo constante.

JavaScript
import { createHmac, timingSafeEqual } from 'node:crypto';

// corpo: o corpo ORIGINAL da requisição (Buffer ou texto, sem reformatar)
// cabecalho: o valor do cabeçalho de assinatura, por exemplo "sha256=ab12..."
function assinaturaValida(corpo, segredo, cabecalho) {
  const esperada = 'sha256=' + createHmac('sha256', segredo).update(corpo).digest('hex');
  const a = Buffer.from(cabecalho ?? '');
  const b = Buffer.from(esperada);
  return a.length === b.length && timingSafeEqual(a, b);
}

Node.js.

Python
import hashlib
import hmac


def assinatura_valida(corpo: bytes, segredo: str, cabecalho: str | None) -> bool:
    esperada = "sha256=" + hmac.new(segredo.encode(), corpo, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperada.encode(), (cabecalho or "").encode())
PHP
<?php
// $corpo: o corpo ORIGINAL da requisição, por exemplo file_get_contents('php://input')
// $cabecalho: por exemplo $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? null
function assinaturaValida(string $corpo, string $segredo, ?string $cabecalho): bool
{
    $esperada = 'sha256=' . hash_hmac('sha256', $corpo, $segredo);
    return hash_equals($esperada, $cabecalho ?? '');
}

Perguntas frequentes

Qual a diferença entre HMAC e um hash comum?

Qualquer pessoa consegue calcular um hash comum de uma mensagem. O HMAC exige a chave secreta, então só quem a tem consegue gerar ou conferir o código, o que prova a origem da mensagem.

Por que o meu HMAC não bate com o do servidor?

As causas mais comuns são o formato da chave (texto, hexadecimal ou Base64), uma mensagem diferente da original (espaços, quebra de linha no fim, JSON reformatado), o algoritmo errado e o uso de um corpo de requisição já alterado. Confira a chave e a mensagem byte a byte.

HMAC é criptografia?

Não. O HMAC não esconde o conteúdo da mensagem, ele só permite verificar se ela é autêntica e não foi modificada. Para esconder o conteúdo, é preciso criptografar.

É seguro colar a minha chave aqui?

O cálculo acontece no seu navegador e a chave não é enviada ao PraDev. Mesmo assim, chaves de produção são credenciais: prefira usar uma chave de teste, e nunca compartilhe uma chave real.

Como comparar assinaturas no servidor com segurança?

Use uma comparação de tempo constante, como crypto.timingSafeEqual no Node.js ou hmac.compare_digest no Python, em vez de ==, para não vazar informação pelo tempo de resposta.