github.com/go-jose/go-jose/v4 (продолжение go-jose от Square) реализует JWS, JWE, JWK и JWT, поэтому встречается везде, где сервисы на Go обмениваются зашифрованными или подписанными токенами. В версии 4.1.6 подпись и проверка работали для семейств HS, RS, PS и ES, а также для EdDSA; имена алгоритмов ES256K, Ed25519 и Ed448 библиотека не распознаёт.
В версии 4 список алгоритмов стал обязательным: jwt.ParseSigned(token, nil) завершается ошибкой no signature algorithms specified, поэтому токен можно разобрать только с алгоритмами, которые выбрали вы. Неподписанные токены разбираются, если в этом списке есть none, но проверку через Claims(key) они не проходят никогда: прочитать такой токен можно только через UnsafeClaimsWithoutVerification, имя которого прямо предупреждает об отсутствии проверки.
Проверка разделена на два шага, и в этом подвох. token.Claims(key, &claims) проверяет подпись и заполняет структуру: он без всякой ошибки вернул утверждения токена, срок действия которого истёк час назад. Срок действия, начало срока действия, издатель и аудитория проверяются только в claims.Validate() со значением jwt.Expected или в ValidateWithLeeway, и даже эту проверку токен без exp проходит, поэтому убедитесь, что поле Expiry заполнено, как это делает пример. Validate допускает расхождение часов jwt.DefaultLeeway, равное одной минуте, что подтвердила проверка.
Ключи типизированы. Токен HS256, подписанный текстом PEM в качестве ключа, не прошёл проверку с *ecdsa.PublicKey (ошибка error in cryptographic primitive), но прошёл, когда те же байты PEM передали как ключ, поэтому храните ключи в виде разобранных ключей Go, а не байтов. ES256 не принимает ключ P-384 и выдаёт expected 256 bit key, got 384 bits instead. Подпись ES256 в кодировке DER отклоняется с той же общей ошибкой error in cryptographic primitive, что и подделка; длину подписи покажет отладчик JWT.
Заголовок и алгоритмы зашифрованных токенов показывает инспектор JWE; для наборов ключей есть проверка JWKS, которая показывает, что публикует поставщик, и конвертер JWK, который преобразует ключи между JWK и PEM.