jose4j implementa JWS, JWE, JWK y JWT sobre los propios proveedores del JDK, con JsonWebSignature para firmar y un JwtConsumer creado con JwtConsumerBuilder para la verificación y la comprobación de los claims. La 0.9.7 superó la prueba de ida y vuelta con HS, RS, PS y ES de 256/384/512 y EdDSA; ES256K, Ed25519 y Ed448 no son nombres de algoritmo reconocidos.
Los valores predeterminados bloquean los dos ataques clásicos, pero dejan abierto el algoritmo. none se rechaza ('none' is a blocked algorithm.) salvo que las firmas se desactiven explícitamente, y el tipo de clave tiene que encajar: un token RS256 contra una clave EC y un token HS256 con el texto PEM de la clave EC como clave fallaron ambos (cannot be used for HMAC verification). Sin embargo, se acepta cualquier otro algoritmo que la clave pueda ejecutar, así que fíjalo con setJwsAlgorithmConstraints(ConstraintType.PERMIT, ...), como hace el ejemplo. Un HmacKey construido a partir de los bytes PEM verificó el token HS256 falsificado: las claves deben salir de la configuración, nunca de lo que afirma el token.
Los tamaños de clave se validan: ES256 rechaza una clave P-384 (expects a key using P-256 but was P-384) y HS256 rechazó una clave de 16 bytes porque el RFC 7518 exige claves al menos tan largas como la salida del hash. Las firmas ES256 son el r‖s en bruto de 64 bytes; una firma DER falla con Invalid JWS Signature, y el decodificador de JWT muestra la longitud.
Los valores predeterminados de los claims tiran en sentidos opuestos: la ausencia de tolerancia de desfase de reloj es más estricta de lo que espera la mayoría de los equipos, y la ausencia de exp obligatorio, más laxa. setRequireExpirationTime(), setExpectedIssuer(), setExpectedAudience() y setAllowedClockSkewInSeconds() deben estar en todo consumidor que lea tokens de otro servicio.
Para los tokens cifrados, el inspector de JWE muestra qué contiene un JWE generado con jose4j.