Gerador de HMAC e verificador de assinaturas
Calcula HMAC-SHA-1, SHA-256, SHA-384 e SHA-512 a partir de uma mensagem e de uma chave, e identifica de qual veio uma assinatura dada.
Introduza uma chave para calcular as assinaturas.
O que esta ferramenta faz
O HMAC transforma uma mensagem e um segredo partilhado numa assinatura curta. Quem tiver o mesmo segredo pode recalculá-la e ver se a mensagem chegou sem alterações e se veio de alguém que também conhece o segredo. Esta ferramenta calcula as quatro variantes habituais de uma vez e, dada uma assinatura que lhe enviaram, diz-lhe qual delas a produziu.
Esse segundo sentido costuma ser a razão por que as pessoas chegam aqui. Um webhook falha a verificação, e a pergunta verdadeira não é «esta assinatura é válida» mas «qual das várias coisas plausíveis estou a fazer de forma diferente do remetente».
A chave é onde isto corre mal
O HMAC assina bytes com bytes. A mensagem costuma ser evidente — o corpo do pedido em bruto — mas a chave quase nunca é, porque um segredo chega como cadeia e uma cadeia só é bytes depois de decidir como a ler:
a3f2 -> 61 33 66 32 4 bytes como texto a3f2 -> a3 f2 2 bytes como hex
As duas leituras são legítimas, ambas produzem uma assinatura perfeitamente bem formada, e as duas assinaturas não têm nada em comum. Nada o avisa: não há erro, não há queixa de comprimento, apenas um valor que não coincide com o que o remetente calculou. É por isso que aqui a codificação da chave é uma escolha visível e não um palpite: quando uma assinatura não coincide, é a primeira coisa a trocar.
Como orientação grosseira: um segredo com um prefixo como whsec_ ou uma sequência de letras maiúsculas e minúsculas e dígitos costuma ser lido como texto; uma cadeia de exatamente 32 ou 64 caracteres que use apenas 0-9 e a-f é normalmente hexadecimal; e uma que termine em = é quase de certeza Base64. Mas consulte a documentação do remetente em vez da forma, porque a forma não é prova.
A mensagem tem de ser os bytes exatos
A outra metade de uma divergência é a mensagem. O HMAC é definido sobre bytes, por isso tudo o que mude os bytes muda a assinatura por completo: não há classificação parcial nem quase acerto.
- Voltar a serializar o JSON. Analisar um corpo e voltar a gerá-lo pode reordenar chaves, mudar espaços ou normalizar números. Assine e verifique o corpo em bruto que recebeu, nunca uma cópia que foi e voltou.
- Uma quebra de linha final. Algumas ferramentas acrescentam uma ao guardar o corpo num ficheiro; é um byte, e muda tudo.
- A codificação de caracteres. Um corpo com texto não ASCII tem de ser lido com a mesma codificação dos dois lados — na prática, UTF-8.
- Compressão ou middleware. Se algo à frente do seu manipulador descomprime ou reescreve o corpo, verifique antes de isso acontecer, não depois.
Muitos fornecedores também não assinam apenas o corpo. A Stripe assina uma marca temporal e o corpo unidos por um ponto; a AWS assina um pedido canónico construído a partir do método, do caminho, dos cabeçalhos e de um hash da carga. Se a verificação falhar contra o corpo simples, a cadeia assinada provavelmente não é o corpo simples — isso está documentado do lado do remetente e vale a pena ler antes de continuar a depurar.
Porque é que o SHA-1 é oferecido aqui e não na ferramenta de hash
A ferramenta de hash marca o SHA-1 como partido. Esta lista o HMAC-SHA-1 sem aviso, e isso é deliberado, não um descuido.
O SHA-1 é inútil para assinaturas e certificados porque se conseguem construir colisões: dois documentos diferentes podem ser levados a partilhar o mesmo resumo. O HMAC não depende dessa propriedade. A sua segurança assenta na chave secreta, e a construção — resumir a mensagem duas vezes, com a chave misturada em ambas — aguenta mesmo quando o hash subjacente é fraco a colisões. O HMAC-SHA-1 continua sólido e é o que o OAuth 1.0a e a assinatura antiga da AWS usam, por isso uma ferramenta que se recusasse a calculá-lo seria simplesmente menos útil sem ser mais segura.
Para algo novo, o SHA-256 é a escolha sensata. Resumos mais longos não são significativamente mais fortes aqui — o teto de segurança é a chave, não o comprimento do resumo — por isso o SHA-384 e o SHA-512 só valem a pena quando algo com que tem de interoperar os pede.
Comparar assinaturas em segurança
Esta página compara com uma comparação de cadeias normal, e aqui isso está bem: a chave está consigo, por isso não há nada a fugir. Num servidor que verifica um pedido que chega, não está bem. Uma comparação normal para no primeiro byte diferente, por isso o tempo que demora revela que parte de um palpite estava correta, e um atacante que possa enviar muitos pedidos consegue recuperar uma assinatura válida byte a byte.
Use a comparação em tempo constante que a sua plataforma oferece — crypto.timingSafeEqual em Node, hmac.compare_digest em Python, hash_equals em PHP — sobre os bytes em bruto e não sobre cadeias hexadecimais. A par disso, compare com uma assinatura que tenha calculado e não confie num algoritmo indicado no pedido, e recuse uma mensagem cuja marca temporal esteja longe de agora, para que uma assinatura válida antiga não possa ser repetida.
O HMAC não é um hash nem uma assinatura
Aqui confundem-se três coisas, e a diferença importa para o que se pode afirmar depois:
- Um hash recebe uma mensagem e produz um resumo. Qualquer pessoa o pode calcular, por isso prova que a mensagem não mudou por acidente, não que veio de alguém em particular.
- Um HMAC recebe uma mensagem e um segredo partilhado. As duas partes têm a mesma chave, por isso prova que o remetente conhecia o segredo. Não pode provar qual das duas enviou, porque qualquer uma o poderia ter produzido.
- Uma assinatura usa uma chave privada que só o remetente tem, e uma chave pública com que qualquer um pode verificar. É isso que dá o não repúdio: o remetente não a pode negar depois.
Assim, o HMAC é a ferramenta certa entre dois sistemas que já partilham um segredo — webhooks, APIs internas, tokens de sessão — e a errada quando é preciso provar a um terceiro quem enviou alguma coisa. Note também que autentica mas não esconde: a mensagem viaja em claro, e o HMAC nada diz sobre confidencialidade.
Perguntas frequentes
- A minha assinatura não coincide. O que verifico primeiro?
- A codificação da chave e depois os bytes da mensagem. Um segredo que parece hexadecimal é muitas vezes pretendido como hexadecimal e não como texto, e os dois produzem assinaturas completamente diferentes sem erro de qualquer dos lados. Depois, certifique-se de que assina o corpo em bruto tal como foi recebido e não uma cópia voltada a serializar.
- Porque é que o SHA-1 é oferecido aqui se a ferramenta de hash diz que está partido?
- Porque o HMAC não assenta na resistência a colisões, que é a propriedade que o SHA-1 perdeu. A sua segurança vem da chave. O HMAC-SHA-1 continua sólido e em uso pelo OAuth 1.0a e pela assinatura antiga da AWS, embora o SHA-256 seja a predefinição certa para algo novo.
- Um resumo mais longo é mais seguro?
- Não de forma significativa. A força de um HMAC é limitada pelo segredo e não pelo comprimento do resumo, por isso o SHA-512 não é quatro vezes melhor do que o SHA-256. Escolha o que a outra parte espera.
- Qual é a diferença entre HMAC e uma assinatura digital?
- O HMAC usa um segredo que ambas as partes conhecem, por isso prova que o remetente conhecia o segredo mas não qual das partes enviou. Uma assinatura digital usa uma chave privada que só o remetente tem, de modo que um terceiro a pode verificar e o remetente não a pode negar. Se precisa dessa última propriedade, o HMAC é a ferramenta errada.
- Devo comparar assinaturas com ===?
- Num servidor, não. Uma comparação normal regressa assim que os bytes diferem, e esse tempo revela que parte de uma assinatura adivinhada estava certa. Use a comparação em tempo constante da sua plataforma sobre os bytes em bruto. Nesta página não importa, porque a chave já está consigo.
- A minha chave é enviada para algum lado?
- Não. Tudo é calculado no seu navegador com a Web Crypto API; a mensagem e a chave nunca saem do seu dispositivo.