Pular para o conteúdo
ecdsa.com
golang-jwt/jwt (Go)Go

Mensagem de erro

token signature is invalid: key is of invalid type: ECDSA verify expects *ecdsa.PublicKey

Também aparece como

  • 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

A v5 indica o tipo esperado (“ECDSA verify expects *ecdsa.PublicKey”, “HMAC verify expects []byte”); a v4 imprime apenas “key is of invalid type”. Como a v5 classifica o erro como `ErrTokenSignatureInvalid`, à primeira vista ele parece uma falha de assinatura.

golang-jwt/jwt (Go) — jwt.ErrInvalidKeyType

O que significa

O valor que seu `Keyfunc` retornou (ou a chave passada para `SignedString`) tem o tipo Go errado para o algoritmo do token. O golang-jwt faz uma asserção de tipo sobre a chave: a verificação ES* precisa de `*ecdsa.PublicKey`, RS*/PS* precisam de `*rsa.PublicKey`, EdDSA precisa de `ed25519.PublicKey` e HS* precisa de `[]byte`; para assinar, é preciso a chave privada correspondente. Nenhuma operação criptográfica foi executada — a chave nem teve a chance de estar errada; ela era o tipo errado de objeto.

Por que acontece

Como corrigir

  1. 1.

    Converter o PEM em uma chave tipada uma única vez

    O golang-jwt inclui funções auxiliares para cada tipo de chave. Faça a conversão na inicialização e retorne a chave tipada no 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.

    Retornar segredos HMAC como []byte

    Converta o segredo em bytes e fixe `WithValidMethods` no algoritmo HMAC, para que tokens com um `alg` assimétrico não cheguem a esse trecho do código.

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

Erros relacionados

Ver toda a base de erros de assinatura