Fehlermeldung
go-jose/go-jose: error in cryptographic primitive
Auch ausgegeben als
- square/go-jose: error in cryptographic primitive
go-jose v2 (importiert als gopkg.in/square/go-jose.v2) verwendete das Präfix „square/go-jose:“; v3 und v4 verwenden „go-jose/go-jose:“. Derselbe Fehler wird auch zurückgegeben, wenn die JWE-Entschlüsselung fehlschlägt.
go-jose (Go) — jose.ErrCryptoFailure from JSONWebSignature.Verify / jwt.JSONWebToken.Claims
Was der Fehler bedeutet
Der allgemeine Fehler von go-jose bei der Signaturprüfung (oder Entschlüsselung), `jose.ErrCryptoFailure`. Die JWS ließ sich parsen, und der Algorithmus war erlaubt, aber die Prüfung der Signatur mit dem übergebenen Schlüssel ist fehlgeschlagen. go-jose sagt absichtlich nicht mehr – ein falscher Schlüssel und ein verändertes Token sehen für die prüfende Seite gleich aus –, deshalb lautet die Frage immer: Welchen Schlüssel hast du übergeben, und wurde das Token verändert?
Warum der Fehler auftritt
Der Schlüssel gehört nicht zum Signierer
häufigEin Schlüssel aus einer anderen Umgebung oder von einem anderen Mandanten oder ein öffentlicher Schlüssel, den der Aussteller bei einer Rotation ersetzt hat.
Der Schlüsselsatz wurde ohne kid durchsucht
häufigCode, der `keys.Keys[0]` statt `keys.Key(kid)` verwendet, prüft mit dem ersten Schlüssel des Satzes. Das funktioniert, bis der Aussteller einen zweiten Schlüssel veröffentlicht.
Header oder Payload wurde verändert
gelegentlichDie Signatur deckt genau die base64url-Bytes ab. Wird die Payload neu serialisiert oder werden Teile zweier Tokens kombiniert, schlägt die Prüfung fehl.
Entschlüsselung mit dem falschen privaten Schlüssel
gelegentlichBei JWE-Tokens bedeutet derselbe Fehler, dass sich der Schlüssel für die Inhaltsverschlüsselung (Content Encryption Key) nicht entpacken ließ oder das Authentifizierungs-Tag die Prüfung nicht bestanden hat – das Token wurde für einen anderen Empfängerschlüssel verschlüsselt.
So behebst du den Fehler
- 1.
Schlüssel per kid auswählen, dann Claims validieren
Ermittle über den `kid` aus dem Header genau einen Schlüssel aus dem JWKS des Ausstellers, prüfe die Signatur und validiere dann `iss`, `aud` und `exp` mit `Claims.Validate` – go-jose prüft Claims nicht von sich aus.
go // keys: *jose.JSONWebKeySet fetched from the issuer's jwks_uri parsed, err := jwt.ParseSigned(raw, []jose.SignatureAlgorithm{jose.ES256}) if err != nil { return err } kid := parsed.Headers[0].KeyID matches := keys.Key(kid) // all keys with this kid if len(matches) != 1 { return fmt.Errorf("no unique key for kid %q", kid) } var claims jwt.Claims if err := parsed.Claims(matches[0].Key, &claims); err != nil { return err } return claims.Validate(jwt.Expected{Issuer: "https://issuer.example.com/", AnyAudience: jwt.Audience{"api"}, Time: time.Now()})