Fehlermeldung
Error(InvalidSignature)
Auch ausgegeben als
- called `Result::unwrap()` on an `Err` value: Error(InvalidSignature)
- InvalidSignature
`{:?}` gibt `Error(InvalidSignature)` aus, `{}` gibt `InvalidSignature` aus; `.unwrap()` löst eine Panic mit „called `Result::unwrap()` on an `Err` value: Error(InvalidSignature)“ aus.
jsonwebtoken (Rust crate) — ErrorKind::InvalidSignature from decode()
Was der Fehler bedeutet
Das Crate `jsonwebtoken` hat das Token geparst und seinen Algorithmus akzeptiert, aber die Signatur hat die Prüfung mit dem `DecodingKey`, den du übergeben hast, nicht bestanden. `Error(InvalidSignature)` ist die Form `Debug`, die du in Logs und bei Panics von `unwrap()` siehst; die Form `Display` ist nur `InvalidSignature`. Das Crate unterscheidet nicht zwischen „falscher Schlüssel“ und „verändertes Token“ – beides bedeutet, dass die Signatur für diesen Schlüssel nicht gültig ist.
Warum der Fehler auftritt
Der DecodingKey gehört nicht zum Signierer
häufigEin Schlüssel aus einer anderen Umgebung, ein hartkodierter Schlüssel, nachdem der Aussteller seine Schlüssel rotiert hat, oder ein JWK, der nach seiner Position statt nach `kid` ausgewählt wird.
Die ECDSA-Signatur des Tokens ist DER-kodiert
gelegentlichEin von Hand gebautes Token mit einer Signatur aus einem KMS oder aus OpenSSL enthält DER (~71 Byte) statt des 64 Byte langen r‖s, das ES256 verlangt; ein solches Token lässt sich nie erfolgreich prüfen.
Die Bytes des HS256-Secrets unterscheiden sich
gelegentlich`DecodingKey::from_secret(b"...")` auf der einen und `from_base64_secret("...")` auf der anderen Seite erzeugen aus demselben Konfigurationsstring unterschiedliche Schlüssel.
So behebst du den Fehler
- 1.
Fehlerart explizit behandeln
Bilde `ErrorKind::InvalidSignature` auf 401 ab und halte diesen Fall getrennt vom Ablauf, damit Clients es mit einem Token, das die Prüfung nie bestehen kann, nicht erneut versuchen.
rust use jsonwebtoken::errors::ErrorKind; match decode::<Claims>(&token, &key, &validation) { Ok(data) => Ok(data.claims), Err(e) => match e.kind() { ErrorKind::InvalidSignature => Err(AuthError::Unauthorized), // wrong key or tampered token ErrorKind::ExpiredSignature => Err(AuthError::Expired), _ => Err(AuthError::BadToken), }, } - 2.
Schlüssel anhand von kid aus dem JWKS des Ausstellers auswählen
`JwkSet::find` und `DecodingKey::from_jwk` wählen genau den Schlüssel, den der Aussteller im Header nennt.
rust use jsonwebtoken::{decode_header, jwk::JwkSet, DecodingKey}; let header = decode_header(&token)?; let kid = header.kid.ok_or(AuthError::BadToken)?; let jwk = jwks.find(&kid).ok_or(AuthError::UnknownKey)?; // jwks: JwkSet fetched from the issuer let key = DecodingKey::from_jwk(jwk)?;