Fehlermeldung
Firebase\JWT\SignatureInvalidException: Signature verification failed
Auch ausgegeben als
- PHP Fatal error: Uncaught Firebase\JWT\SignatureInvalidException: Signature verification failed
Wird die Ausnahme nicht abgefangen, gibt PHP „PHP Fatal error: Uncaught Firebase\JWT\SignatureInvalidException: Signature verification failed in …/JWT.php“ aus.
firebase/php-jwt (PHP) — Firebase\JWT\SignatureInvalidException from JWT::decode
Was der Fehler bedeutet
php-jwt hat das Token geparst und den Algorithmus für den übergebenen Schlüssel akzeptiert, aber die Signaturprüfung hat false ergeben: Schlüssel und Token gehören nicht zusammen, oder das Token wurde nach dem Signieren verändert. `SignatureInvalidException` ist eine Unterklasse von `UnexpectedValueException`, deshalb kann ein allgemeiner catch-Block sie zwischen Parsing-Fehlern verstecken.
Warum der Fehler auftritt
Der konfigurierte Schlüssel gehört nicht zum Signierer
häufigEin öffentlicher Schlüssel, der aus einer anderen Umgebung kopiert wurde, oder ein Schlüssel, der beim Aussteller rotiert wurde. Firebase Auth und Google signieren ID-Tokens mit Schlüsseln, die alle paar Tage wechseln.
Ein Schlüssel aus dem Schlüsselsatz, ausgewählt ohne kid
häufigCode, der den ersten Schlüssel eines JWKS nimmt (zum Beispiel `reset(JWK::parseKeySet($jwks))`), funktioniert nur so lange, bis der Aussteller mit einem anderen Schlüssel aus dem Set signiert.
Das HMAC-Secret unterscheidet sich zwischen den Diensten
gelegentlichBei HS256 ergibt jeder Unterschied im Secret-String – Whitespace, ein abschließender Zeilenumbruch aus einer Datei, base64 gegenüber Rohbytes – einen anderen MAC.
Das Token wurde nach dem Signieren verändert
gelegentlichHeader oder Payload wurden neu kodiert, oder ein Token wurde aus Teilen zweier Tokens zusammengesetzt.
So behebst du den Fehler
- 1.
Ganzen Schlüsselsatz übergeben und php-jwt per kid auswählen lassen
`JWT::decode` akzeptiert ein nach `kid` indiziertes Array aus Objekten vom Typ `Key` (aus `JWK::parseKeySet`) oder ein `CachedKeySet`, das sich bei einer Rotation außerdem selbst aktualisiert.
php use Firebase\JWT\CachedKeySet; use Firebase\JWT\JWT; use GuzzleHttp\Client; use GuzzleHttp\Psr7\HttpFactory; // Keys selected by the token's kid, fetched from the issuer's JWKS and cached (PSR-6). $keys = new CachedKeySet( 'https://issuer.example.com/.well-known/jwks.json', new Client(), new HttpFactory(), $cache, // any PSR-6 cache pool 3600, // cache lifetime in seconds true // rate-limit refetches on unknown kids ); $claims = JWT::decode($token, $keys); - 2.
Beide Schlüsselhälften vergleichen
Weicht der aus dem privaten Schlüssel des Ausstellers abgeleitete öffentliche Schlüssel von dem ab, den du konfiguriert hast, kann die Prüfung der Signatur nicht gelingen.
bash # Do the issuer's private key and your public key belong together? openssl pkey -in issuer-private.pem -pubout | sha256sum openssl pkey -pubin -in configured-public.pem | sha256sum