python-jose implementa JWS, JWE, JWK y JWT con backends intercambiables —ecdsa en Python puro, pycryptodome o cryptography—; la comprobación instaló el extra cryptography. Años de tutoriales de FastAPI y Flask la popularizaron, pero el desarrollo es lento: la 3.4.0 (febrero de 2025) llegó casi 4 años después de la 3.3.0, y los proyectos nuevos suelen elegir PyJWT, jwcrypto o joserfc en su lugar.
algorithms es opcional en jwt.decode(), y sin él el algoritmo sale del encabezado del token. Junto con el aviso de seguridad GHSA-3qf3-8w2g-rqmx (CVE-2026-85394), publicado en septiembre de 2026 y sin corregir en la 3.5.0, eso es explotable: la protección contra el uso de claves públicas como secretos HMAC reconoce el texto PEM y OpenSSH, pero no la misma clave en bytes DER. La comprobación lo reprodujo: un token HS256 cuya clave HMAC era la clave pública DER se verificó contra esa clave cuando se omitió algorithms, y se rechazó con The specified alg value is not allowed en cuanto se pasó algorithms=["ES256"]. Pasa siempre algorithms, conserva las claves públicas como cadenas PEM y comprueba los secretos con el comprobador de secretos JWT.
Su conjunto de algoritmos es el más antiguo de las bibliotecas de Python: solo las familias HS, RS y ES. PS256, EdDSA y ES256K lanzan Algorithm … not supported., así que los tokens de proveedores que se pasaron a Ed25519 o a RSA-PSS no se pueden verificar. ES256 tampoco está ligado a P-256: una clave P-384 produjo una firma de 96 bytes bajo un encabezado ES256 que python-jose verificó, pero que otras bibliotecas, como jose y PyJWT, rechazan.
Las firmas ES256 son 64 bytes de r‖s en bruto, y una firma DER falla con Signature verification failed.; el decodificador de JWT muestra qué forma lleva un token. exp es opcional y la tolerancia es cero salvo que configures require_exp y leeway en options, como hace el ejemplo.
Los tokens sin firmar se rechazaron con Unable to find an algorithm for key, incluso con algorithms=["none"].