Сообщение об ошибке
token signature is invalid: key is of invalid type: ECDSA verify expects *ecdsa.PublicKey
Также выводится как
- token signature is invalid: key is of invalid type: HMAC verify expects []byte
- token signature is invalid: key is of invalid type: RSA verify expects *rsa.PublicKey
- key is of invalid type: ECDSA sign expects *ecdsa.PrivateKey
- key is of invalid type
v5 называет ожидаемый тип («ECDSA verify expects *ecdsa.PublicKey», «HMAC verify expects []byte»); v4 выводит только «key is of invalid type». Поскольку v5 относит эту ошибку к `ErrTokenSignatureInvalid`, на первый взгляд она похожа на ошибку проверки подписи.
golang-jwt/jwt (Go) — jwt.ErrInvalidKeyType
Что это означает
Значение, которое вернула ваша `Keyfunc` (или ключ, переданный в `SignedString`), имеет в Go тип, не подходящий для алгоритма токена. golang-jwt проверяет тип ключа утверждением типа (type assertion): для проверки ES* нужен `*ecdsa.PublicKey`, для RS*/PS* — `*rsa.PublicKey`, для EdDSA — `ed25519.PublicKey`, для HS* — `[]byte`; для подписи нужен соответствующий закрытый ключ. Криптографические операции даже не выполнялись: ключ не успел оказаться неверным, это был объект не того вида.
Почему это происходит
Возвращены байты PEM вместо разобранного ключа
частоВозврат `[]byte`, прочитанных из файла `.pem`, работает для HMAC, но не для асимметричных алгоритмов. Сначала байты нужно разобрать в `*ecdsa.PublicKey` или `*rsa.PublicKey`.
Для проверки передан закрытый ключ
часто`*ecdsa.PrivateKey` не принимается там, где требуется `*ecdsa.PublicKey`. Возвращайте `&priv.PublicKey`, а лучше вообще не допускайте закрытые ключи в код проверки.
Секрет HMAC возвращён как string
частоДля HS256 Keyfunc должна возвращать `[]byte`. Значение типа `string` (например, из `os.Getenv`) не проходит утверждение типа.
Структура или map с JWK вместо криптографического ключа
иногдаКлючи из JWKS, декодированные в структуру или `map[string]any`, ещё не криптографические ключи. Преобразуйте их (например, с помощью `JSONWebKey.Key` из go-jose или поддержки JWKS в keyfunc).
Как исправить
- 1.
Разберите PEM в типизированный ключ один раз
В golang-jwt есть вспомогательные функции для каждого типа ключа. Разбирайте ключ при запуске и возвращайте из Keyfunc типизированный ключ.
go pub, err := jwt.ParseECPublicKeyFromPEM(pemBytes) // ES256/384/512 // rsaPub, err := jwt.ParseRSAPublicKeyFromPEM(pemBytes) // RS*/PS* // edPub, err := jwt.ParseEdPublicKeyFromPEM(pemBytes) // EdDSA if err != nil { log.Fatal(err) } token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return pub, nil }, jwt.WithValidMethods([]string{"ES256"})) - 2.
Возвращайте секреты HMAC как []byte
Преобразуйте секрет в байты и ограничьте `WithValidMethods` алгоритмом HMAC, чтобы токены с асимметричным `alg` не могли попасть в эту ветку кода.
go secret := []byte(os.Getenv("JWT_HMAC_SECRET")) // []byte, not string token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return secret, nil }, jwt.WithValidMethods([]string{"HS256"}))