Mensaje de error
Error(InvalidSignature)
También se muestra como
- called `Result::unwrap()` on an `Err` value: Error(InvalidSignature)
- InvalidSignature
`{:?}` imprime `Error(InvalidSignature)` y `{}` imprime `InvalidSignature`; `.unwrap()` entra en pánico con «called `Result::unwrap()` on an `Err` value: Error(InvalidSignature)».
jsonwebtoken (Rust crate) — ErrorKind::InvalidSignature from decode()
Qué significa
El crate `jsonwebtoken` analizó el token y aceptó su algoritmo, pero la firma no se verificó con la `DecodingKey` que pasas. `Error(InvalidSignature)` es la forma `Debug` que ves en los registros y en los pánicos de `unwrap()`; la forma `Display` es solo `InvalidSignature`. El crate no distingue entre «clave incorrecta» y «token modificado»: en ambos casos la firma no es válida para esta clave.
Por qué ocurre
La DecodingKey no pertenece al firmante
frecuenteUna clave de otro entorno, una clave fijada en el código después de que el emisor rotara sus claves, o la elección de una JWK por su posición en lugar de por `kid`.
La firma ECDSA del token está codificada en DER
ocasionalUn token construido a mano con una firma de un KMS o de OpenSSL lleva DER (~71 bytes) en lugar del r‖s de 64 bytes que exige ES256; nunca supera la verificación.
Los bytes del secreto HS256 no coinciden
ocasional`DecodingKey::from_secret(b"...")` en un lado y `from_base64_secret("...")` en el otro producen claves distintas a partir de la misma cadena de configuración.
Cómo solucionarlo
- 1.
Tratar explícitamente el tipo de error
Asigna `ErrorKind::InvalidSignature` a 401 y mantenlo separado de la caducidad, para que los clientes no reintenten con un token que nunca podrá pasar la verificación.
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.
Seleccionar la clave del JWKS del emisor por kid
`JwkSet::find` y `DecodingKey::from_jwk` eligen exactamente la clave que el emisor indica en el encabezado.
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)?;