Mensaje de error
The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
También se muestra como
- jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
PyJWT (Python) — jwt.exceptions.InvalidKeyError from HMACAlgorithm.prepare_key
Qué significa
Se pidió a PyJWT que usara un PEM de clave pública, de clave privada o de certificado como secreto de un algoritmo HMAC (HS256/384/512), y se negó. Esta protección existe por una clase de errores de JWT muy conocida: si un verificador acepta algoritmos RS/ES y HS con el mismo argumento de clave, cualquiera que conozca la clave pública podría calcular un HMAC válido sobre un token falsificado. Aquí, el encabezado del token indicaba un algoritmo HMAC que tu lista de permitidos admite.
Por qué ocurre
La lista de permitidos mezcla algoritmos HMAC y asimétricos
frecuenteCon `algorithms=["RS256", "HS256"]` y una clave pública, un token HS256 intenta usar esa clave pública como secreto HMAC. Aceptarlo dejaría pasar un token falsificado; PyJWT lo impide.
El servicio está configurado para HS256, pero tiene un PEM
ocasionalUna configuración que dice `JWT_ALGORITHM=HS256` mientras `JWT_KEY` contiene un archivo PEM. Decide qué esquema usa realmente el emisor y haz que ambos valores coincidan.
Alguien está poniendo a prueba el verificador
ocasionalLos tokens con `alg: "HS256"` que llegan a una API cuyo emisor firma con RSA o ECDSA son un sondeo clásico de la debilidad de confusión de algoritmos. Registra el origen; el error significa que el sondeo fracasó.
Cómo solucionarlo
- 1.
Permitir una sola familia de algoritmos por clave
Pasa, junto con la clave pública del emisor, solo los algoritmos asimétricos que este usa, y mantén la verificación HMAC (si es que la necesitas) en una ruta de código separada con su propio secreto aleatorio.
python # Asymmetric issuer: allow only asymmetric algorithms with the public key. claims = jwt.decode(token, public_key, algorithms=["ES256"], audience="https://api.example.com") # Shared-secret tokens: a random secret, never a PEM, and only HMAC algorithms. claims = jwt.decode(token, HMAC_SECRET, algorithms=["HS256"], audience="internal")