spring-projects / spring-projects/spring-security
NimbusJwtEncoder does not support Edwards Curve signature (EdDSA) family algorithms.
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
Description
It is currently possible to create a NimbusJwtEncoder using an ImmutableJWKSet that contains an Ed25519 key (via OctetKeyPair), but it is not possible to use that encoder to generate a JWT signed with Ed25519 (EdDSA).
Problem Details
JwtEncoderParameters.from(header, claims)does not allow custom algorithms in the header.- Only enums implementing
JwsAlgorithmorJwaAlgorithmare allowed. - The default
SignatureAlgorithmenum implementsJwsAlgorithm, but does not include any EdDSA algorithms likeEdDSA(com.nimbusds.jose.JWSAlgorithm.EdDSA).
- Only enums implementing
- Even if a custom implementation of
JwsAlgorithmis provided to represent EdDSA, it does not resolve the problem because of howNimbusJwtEncoderinternally selects a signing key. - During encoding, the
selectJwkmethod is called. This uses aJWKSelectorcreated with a matcher generated by the privatecreateJwkMatchermethod.- Unfortunately,
createJwkMatcherdoes not support the EdDSA algorithm family, which results in the JWKSelector being constructed with a null matcher. - This causes
IllegalArgumentExceptionto be thrown at runtime due to the missing matcher.
- Unfortunately,
When running following code:
val header = JwsHeader.with(FixedSignatureAlgorithm.Ed25519).build()
val claims = JwtClaimsSet.builder()
.issuer(issuer)
.issuedAt(Instant.now())
.expiresAt(expiresAt)
.claim(SESSION_ID_CLAIM_NAME, sessionId)
.build()
jwtEncoder.encode(JwtEncoderParameters.from(header, claims)).tokenValue
public enum FixedSignatureAlgorithm implements JwsAlgorithm {
RS256(JwsAlgorithms.RS256),
RS384(JwsAlgorithms.RS384),
RS512(JwsAlgorithms.RS512),
ES256(JwsAlgorithms.ES256),
ES384(JwsAlgorithms.ES384),
ES512(JwsAlgorithms.ES512),
PS256(JwsAlgorithms.PS256),
PS384(JwsAlgorithms.PS384),
PS512(JwsAlgorithms.PS512),
EdDSA(JWSAlgorithm.EdDSA.getName()),
Ed25519(JWSAlgorithm.Ed25519.getName());
private final String name;
FixedSignatureAlgorithm(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
public static FixedSignatureAlgorithm from(String name) {
for (FixedSignatureAlgorithm value : values()) {
if (value.getName().equals(name)) {
return value;
}
}
return null;
}
}
then such error is thrown:
org.springframework.security.oauth2.jwt.JwtEncodingException: An error occurred while attempting to encode the Jwt: Failed to select a JWK signing key -> The JWK matcher must not be null
at org.springframework.security.oauth2.jwt.NimbusJwtEncoder.selectJwk(NimbusJwtEncoder.java:123)
at org.springframework.security.oauth2.jwt.NimbusJwtEncoder.encode(NimbusJwtEncoder.java:108)
Caused by: java.lang.IllegalArgumentException: The JWK matcher must not be null
at com.nimbusds.jose.jwk.JWKSelector.<init>(JWKSelector.java:51)
at org.springframework.security.oauth2.jwt.NimbusJwtEncoder.selectJwk(NimbusJwtEncoder.java:119)
... 158 common frames omitted
Suggested fix
To support Ed25519/EdDSA, the following would need to be addressed:
- Add EdDSA (
JWSAlgorithm.EdDSA) support to theSignatureAlgorithmenum or allow flexible/custom algorithm headers inJwtEncoderParameters. - Update
createJwkMatcherinNimbusJwtEncoderto recognize and match EdDSA algorithm family keys likeOctetKeyPairwithCurve.Ed25519.
Used versions
com.springframework.security:spring-security-oauth2-jose:6.3.3
com.nimbusds:nimbus-jose-jwt:9.40
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in NimbusJwtEncoder at selectJwk and createJwkMatcher, then inspect SignatureAlgorithm and JwtEncoderParameters to understand how the requested algorithm reaches key selection. Reproduce the supplied Ed25519 example and verify that an OctetKeyPair with Curve.Ed25519 can be selected and used to produce a signed JWT.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100