Migrate to Jakarta EE 10, Jersey 3.x, and Jetty 12
Migrates javax namespaces to their jakarta counterparts.
Performs the following notable version bumps:
- Jakarta Servlet API:
4.0.1->6.0.0(latest) - JAXB:
2.3.6->4.0.5(latest) - Jersey:
2.41->3.1.6(latest) - Jetty:
10.0.18->12.0.9(latest)
The following changes were necessary due to compatibility issues with Jakarta EE 10:
io.jsonwebtoken:jjwt:0.9.1->0.12.5- ~Signing and verifying of JWTs with Alpine's
SecretKeyno longer worked. I'm not sure why it worked before, but now the library complained about AES keys not being suitable for HMAC signing. I modified theJsonWebTokenclass to use Alpine's public/private key pair instead, which works. It changes the signature algorithm toRS512. I believe this change makes sense anyway.~ - The above was resolved by converting the
SecretKeygenerated forAESto an appropriateHmacSHA*algorithm (https://github.com/stevespringett/Alpine/pull/570/commits/a3687b4998b046c49f46e95d5af3282a6449040c)
- ~Signing and verifying of JWTs with Alpine's
- The default implementation of
jakarta.jsonis Eclipse Parsson. Replacedorg.glassfish:javax-jsonwith it. - The default implementation of
jakarta.mail-apiis Eclipse Angus. Added it.
Closes #402
FTR, Dependency-Track has been migrated accordingly. The test suite passes locally, and manual testing of the running application did not yield any complications. Pending PR is here: https://github.com/DependencyTrack/dependency-track/pull/3730
@stevespringett Thoughts on this part?
io.jsonwebtoken:jjwt:0.9.1->0.12.5
- Signing and verifying of JWTs with Alpine's SecretKey no longer worked. I'm not sure why it worked before, but now the library complained about AES keys not being suitable for HMAC signing. I modified the JsonWebToken class to use Alpine's public/private key pair instead, which works. It changes the signature algorithm to RS512. I believe this change makes sense anyway.
I was originally under the impression that the public/private key pair was used for JWT signing, but it turned out that the secret key was used instead. Is it a hard requirement to have this work with the secret key?
@nscuro The SecretKey is a symmetrical key used to sign the JWT (e.g. HS512). The private/public key pair are asymmetrical keys for the encryption and decryption of data. Both key types are required.
Hmmm yes, I was not planning to remove any of the keys. Just wondering which ones are supposed to be used for JWT signing.
At the moment, the secret key is used for both data encryption:
https://github.com/stevespringett/Alpine/blob/e747ed50be81f9fc955a44bf8f7786a26973e99f/alpine-infra/src/main/java/alpine/security/crypto/DataEncryption.java#L82-L85
and signing:
https://github.com/stevespringett/Alpine/blob/e747ed50be81f9fc955a44bf8f7786a26973e99f/alpine-server/src/main/java/alpine/server/auth/JsonWebToken.java#L94-L96
The public/private key pair is unused.
The secret key is generated with algorithm AES:
https://github.com/stevespringett/Alpine/blob/e747ed50be81f9fc955a44bf8f7786a26973e99f/alpine-infra/src/main/java/alpine/security/crypto/KeyManager.java#L166-L171
and the new JJWT version prevents AES keys from being used for HMAC signatures, i.e. it raises the following exception:
Unable to compute HS512 signature. Cause: The signing key's algorithm 'AES' does not equal a valid HmacSHA* algorithm name
IMO it would make sense to use the private key for signing, and the public key for signature verification.
Another option would be to re-use the secret key's content to construct a new SecretKey with hmacSHA256 algorithm:
SecretKey originalKey = KeyManager.getInstance().getSecretKey(); // algorithm=AES
SecretKey hmacKey = new SecretKeySpec(originalKey.getEncoded(), "hmacSHA256");
JJWT's checks might be a tad too strict here. Their docs state:
[...] JJWT will assert that the specified key is allowed to be used for that algorithm when possible according to the JWT specification requirements.
There is no practical reason why a 256bit key generated for AES cannot be used for HMAC256. The way Java generates those keys is virtually the same.
Would the above be preferable over using they public/private key pair?
Can you resolve the conflict?