Перейти к содержимому
ecdsa.com
golang-jwt/jwt (Go)Go

Сообщение об ошибке

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`; для подписи нужен соответствующий закрытый ключ. Криптографические операции даже не выполнялись: ключ не успел оказаться неверным, это был объект не того вида.

Почему это происходит

Как исправить

  1. 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. 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"}))

Связанные ошибки

Открыть всю базу ошибок подписей