Mensaje de error
go-jose/go-jose: error in cryptographic primitive
También se muestra como
- square/go-jose: error in cryptographic primitive
go-jose v2 (importado como gopkg.in/square/go-jose.v2) usaba el prefijo «square/go-jose:»; v3 y v4 usan «go-jose/go-jose:». El mismo error se devuelve cuando falla el descifrado de un JWE.
go-jose (Go) — jose.ErrCryptoFailure from JSONWebSignature.Verify / jwt.JSONWebToken.Claims
Qué significa
Es el fallo genérico de firma (o de descifrado) de go-jose, `jose.ErrCryptoFailure`. El JWS se analizó y el algoritmo estaba permitido, pero falló la verificación de la firma con la clave que se pasó. go-jose no dice más a propósito (para un verificador, una clave equivocada y un token modificado se ven igual), así que la investigación siempre es la misma: ¿qué clave pasaste y se modificó el token?
Por qué ocurre
La clave no pertenece al firmante
frecuenteUna clave de otro entorno o de otro inquilino, o una clave pública que el emisor sustituyó durante la rotación.
Se buscó en el conjunto de claves sin el kid
frecuenteEl código que toma `keys.Keys[0]` en lugar de `keys.Key(kid)` verifica con la primera clave del conjunto. Funciona hasta que el emisor publica una segunda clave.
Se modificó el encabezado o la carga útil
ocasionalLa firma cubre exactamente los bytes base64url. Volver a serializar la carga útil, o combinar partes de dos tokens, rompe la verificación.
Descifrado con la clave privada equivocada
ocasionalEn los tokens JWE, el mismo error significa que no se pudo desenvolver la clave de cifrado del contenido o que la etiqueta de autenticación no se verificó: el token se cifró para otra clave de destinatario.
Cómo solucionarlo
- 1.
Seleccionar la clave por kid y después validar los claims
Obtén exactamente una clave del JWKS del emisor a partir del `kid` del encabezado, verifica y después valida `iss`, `aud` y `exp` con `Claims.Validate`: go-jose no comprueba los claims por sí solo.
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()})