github.com/go-jose/go-jose/v4 (a continuação do go-jose da Square) implementa JWS, JWE, JWK e JWT, e por isso aparece onde quer que serviços Go troquem tokens criptografados ou assinados. A versão 4.1.6 assinou e verificou as famílias HS, RS, PS e ES e o EdDSA; ES256K, Ed25519 e Ed448 não são nomes de algoritmo reconhecidos.
A versão 4 tornou obrigatória a lista de algoritmos: jwt.ParseSigned(token, nil) falha com no signature algorithms specified, de modo que um token só pode ser analisado com algoritmos que você escolheu. Tokens sem assinatura podem ser analisados se none estiver nessa lista, mas Claims(key) nunca os verifica — a única forma de ler um deles é a função de nome explícito UnsafeClaimsWithoutVerification.
A verificação é dividida em duas etapas, e é aí que está a armadilha. token.Claims(key, &claims) verifica a assinatura e preenche a struct — e retornou, sem nenhum erro, as claims de um token que tinha expirado uma hora antes. Expiração, início da validade (not-before), emissor e público-alvo só são verificados por claims.Validate() com um valor jwt.Expected ou por ValidateWithLeeway, e um token sem exp passa até por essa verificação; por isso, confira se Expiry está definido, como faz o exemplo. Validate admite jwt.DefaultLeeway, um minuto, o que o teste confirmou.
As chaves são tipadas. Um token HS256 que usava o texto PEM como chave falhou contra a *ecdsa.PublicKey com error in cryptographic primitive, mas foi verificado quando os mesmos bytes PEM foram passados como chave — mantenha as chaves como chaves Go já analisadas, e não como bytes. O ES256 recusa uma chave P-384 com expected 256 bit key, got 384 bits instead. Uma assinatura ES256 codificada em DER falha com o mesmo erro genérico error in cryptographic primitive de uma assinatura forjada; o depurador de JWT mostra o tamanho da assinatura.
Para tokens criptografados, o inspetor de JWE mostra o cabeçalho e os algoritmos; para conjuntos de chaves, o verificador de JWKS mostra o que um provedor publica, e o conversor de JWK converte chaves entre JWK e PEM.