Zum Inhalt springen
ecdsa.com
golang-jwt/jwt (Go)Go

Fehlermeldung

token signature is invalid: crypto/ecdsa: verification error

Auch ausgegeben als

  • token signature is invalid: crypto/rsa: verification error
  • token signature is invalid: signature is invalid
  • token signature is invalid: ed25519: verification error
  • crypto/ecdsa: verification error

golang-jwt v4 gibt nur den inneren Text zurück, etwa „crypto/ecdsa: verification error“. Verwende `errors.Is(err, jwt.ErrTokenSignatureInvalid)` (v5), statt Strings zu vergleichen.

golang-jwt/jwt (Go) — jwt.ErrTokenSignatureInvalid joined with the algorithm's verification error

Was der Fehler bedeutet

golang-jwt hat das Token geparst, seinen Algorithmus akzeptiert und von deiner `Keyfunc` einen Schlüssel erhalten, aber die Signaturprüfung mit diesem Schlüssel ist fehlgeschlagen. In v5 verknüpft der Fehler `jwt.ErrTokenSignatureInvalid` („token signature is invalid“) mit dem eigenen Fehler des Algorithmus: `crypto/ecdsa: verification error` bei ES*, `crypto/rsa: verification error` bei RS*/PS*, `signature is invalid` bei HS*. Die Bytes des Tokens und der Schlüssel gehören schlicht nicht zusammen.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Schlüssel per kid aus dem JWKS ermitteln

    Lass die Keyfunc den im Header des Tokens genannten Schlüssel aus dem Schlüsselsatz des Ausstellers auswählen und den Schlüsselsatz bei einer Rotation aktualisieren (zum Beispiel mit `github.com/MicahParks/keyfunc`). Lege immer `WithValidMethods` fest.

    go
    import (
    	"context"
    	"github.com/MicahParks/keyfunc/v3"
    	"github.com/golang-jwt/jwt/v5"
    )
    
    // Resolve the verification key from the issuer's JWKS by the token's kid.
    k, err := keyfunc.NewDefaultCtx(ctx, []string{"https://issuer.example.com/.well-known/jwks.json"})
    if err != nil {
    	return err
    }
    token, err := jwt.Parse(raw, k.Keyfunc,
    	jwt.WithValidMethods([]string{"ES256"}),
    	jwt.WithIssuer("https://issuer.example.com/"),
    	jwt.WithAudience("https://api.example.com"))
  2. 2.

    Nachweisen, dass beide Seiten denselben Schlüssel verwenden

    Bilde den Hash des DER-kodierten öffentlichen Schlüssels, den die prüfende Seite verwendet, und den Hash der öffentlichen Hälfte des privaten Schlüssels des Ausstellers. Unterschiedliche Hashes beenden die Untersuchung.

    bash
    # Same key on both sides? Compare SPKI fingerprints.
    openssl pkey -pubin -in verifier-public.pem -outform DER | sha256sum
    openssl pkey -in issuer-private.pem -pubout -outform DER | sha256sum
  3. 3.

    Fehlerklasse behandeln, nicht den String

    golang-jwt v5 stellt Sentinel-Fehler bereit. Bilde eine fehlgeschlagene Signaturprüfung auf 401 ab und weiche nicht darauf aus, andere Schlüssel zu probieren oder die Prüfung zu überspringen.

    go
    switch {
    case errors.Is(err, jwt.ErrTokenSignatureInvalid):
    	return http.StatusUnauthorized // wrong key or tampered token: never retry with another key blindly
    case errors.Is(err, jwt.ErrTokenExpired):
    	return http.StatusUnauthorized // client should refresh
    case errors.Is(err, jwt.ErrTokenMalformed):
    	return http.StatusBadRequest
    }

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen