Guias JWT

Assinatura JWT Inválida: Causas e Como Corrigir

Veja a ordem que uso para depurar assinatura JWT inválida: chave errada, alg incompatível, kid, rotação, encoding e bytes do token alterados.

Por JWTDecoder.toolsÚltima verificação em 2026-09-12

Voz editorial: a primeira pessoa descreve o fluxo de trabalho documentado do JWTDecoder.tools; JWTDecoder.tools é o editor e autor organizacional.

Fluxo para depurar assinatura JWT inválida
Confirmo algoritmo, issuer, kid e seleção de chave antes de mudar a configuração.

Quando encontro assinatura JWT inválida, não começo trocando algoritmos ou desativando verificações até algo “passar”. Preservo o token original, decodifico apenas o necessário para entender alg, kid e iss, e reconstruo o caminho até a fonte de chave que a aplicação realmente confia.

Se já tenho o secret HMAC ou a chave pública RSA esperada, uso o Verificador de Assinatura JWT sobre o token original.

O que uma assinatura inválida realmente me diz

Um JWS assinado tem:

header.payload.signature

A assinatura protege os bytes codificados do cabeçalho e payload. Se a verificação falha, pelo menos um elemento não corresponde ao que o verificador espera.

As causas que procuro primeiro são:

  • secret HMAC errado;
  • chave pública RSA errada;
  • issuer ou tenant errado;
  • kid apontando para outra chave;
  • cache JWKS desatualizado após rotação;
  • algoritmo incompatível;
  • token modificado, truncado ou reformatado;
  • PEM/JWK ou encoding de secret diferente entre sistemas.

1. Preservo o token original

Não edito payload para “testar” uma correção. Alterar:

{"role":"user"}

para:

{"role":"admin"}

muda os bytes assinados. Reencodar o JSON não preserva a assinatura original.

Também evito remover espaços ou recriar segmentos a partir do JSON. A assinatura cobre a representação codificada original, não uma versão semanticamente equivalente do objeto.

2. Leio alg, kid e iss

No Decodificador JWT, procuro algo como:

{
  "alg": "RS256",
  "kid": "key-42"
}

Uso esses valores como pistas, não como política de confiança. alg é informação fornecida pelo token. kid é uma dica de seleção. iss é uma declaração ainda não autenticada até a assinatura ser verificada.

A configuração da aplicação é que deve dizer quais algoritmos, emissores e fontes de chave são aceitos.

3. Confirmo o algoritmo esperado

Se a aplicação foi configurada para RS256, espero uma allowlist explícita que permita RS256. Não mudo para HS256 só porque o token diz alg: HS256.

A RFC 8725 recomenda restringir os algoritmos aceitos. Isso evita confusão de algoritmo e reduz o risco de transformar um problema operacional em uma falha de segurança.

4. Rastreio a chave até o emissor

Para HMAC, confirmo os bytes exatos do segredo compartilhado.

Para RSA, confirmo que a chave pública vem do emissor que a aplicação decidiu confiar.

Erros frequentes:

  • token de produção verificado com chave de desenvolvimento;
  • tenant errado;
  • PEM sem BEGIN/END PUBLIC KEY;
  • certificado fornecido quando a biblioteca espera SPKI;
  • JWKS de outro issuer;
  • cache de chaves antigo;
  • kid correto em um conjunto de chaves errado.

Não basta encontrar alguma chave que faça a assinatura passar. Ela precisa pertencer ao trust path correto.

5. Verifico kid e rotação

Se o token tem kid, comparo com o JWKS confiável atual.

Um kid not found costuma indicar:

  • rotação recente;
  • cache JWKS antigo;
  • ambiente dev/prod misturado;
  • issuer errado;
  • lógica de seleção de chave incorreta.

O guia de JWT kid e JWKS aprofunda essa etapa. Quando já tenho o conjunto de chaves, uso o Validador JWKS para selecionar a chave compatível e verificar a assinatura.

6. Para HS256, verifico o encoding do secret

Dois sistemas podem mostrar a mesma string de configuração e ainda usar bytes diferentes.

Confiro:

  • texto UTF-8 bruto versus Base64 decodificado;
  • espaços e quebras de linha acidentais;
  • secrets diferentes entre ambientes;
  • rotação de segredo;
  • secret curto ou humano demais.

A RFC 8725 alerta para secrets HMAC fracos, que podem permitir tentativa offline. Não resolvo um erro de assinatura trocando uma chave forte por uma senha curta apenas porque é mais fácil de copiar.

7. Se a assinatura passar, continuo validando

Assinatura válida não encerra o diagnóstico. Ainda verifico:

  • exp e nbf;
  • iss;
  • aud;
  • tipo do token;
  • scopes e roles.

Por isso, depois da camada criptográfica, uso o Validador JWT e o Depurador JWT.

O que não faço

Evito estes “atalhos”:

  • desativar verificação de assinatura;
  • aceitar qualquer alg indicado pelo token;
  • baixar e confiar automaticamente em chave de URL controlada pelo token;
  • editar o payload e esperar que a assinatura antiga funcione;
  • tratar decodificação bem-sucedida como verificação bem-sucedida.

Meu checklist de assinatura inválida

  1. Mantenho o JWT compacto original intacto.
  2. Decodifico alg, kid, iss e aud.
  3. Confirmo o algoritmo permitido pela aplicação.
  4. Identifico o emissor confiável e sua fonte de chaves.
  5. Comparo kid com o key set atual.
  6. Investigo rotação, cache, ambiente e tenant.
  7. Em HMAC, confirmo bytes e encoding do secret.
  8. Em RSA, confirmo formato e procedência da chave pública.
  9. Executo a verificação com material de chave confiável.
  10. Se a assinatura passa mas a API ainda retorna 401, sigo para issuer, audience e tempo.

Uma assinatura inválida não é um detalhe de parsing. Para mim, ela significa que o verificador ainda não conseguiu estabelecer integridade e autenticidade com a chave que recebeu; a solução está no caminho de chave, algoritmo ou confiança, não em ignorar a falha.

Fontes e referências

Guias relacionados