I’m trying to implement a solution with the encoder/decoder from the org.springframework.security.oauth2.jwt
package with a shared secret.
But my attempt fails when I try to encode a token with a JwtEncodingException
.
I have asked this question in another form, but here I include a simple ready to execute example, to verify the problem.
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.source.ImmutableSecret;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.security.oauth2.jwt.*;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class EncoderDecoderTest {
public static String secret = "j8IoV1jF67";
public JwtEncoder jwtEncoder() throws JOSEException {
SecretKey originalKey = new SecretKeySpec(secret.getBytes(), "AES");
JWKSource<SecurityContext> immutableSecret = new ImmutableSecret<SecurityContext>(originalKey);
return new NimbusJwtEncoder(immutableSecret);
}
public JwtDecoder jwtDecoder() {
SecretKey originalKey = new SecretKeySpec(secret.getBytes(), "AES");
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withSecretKey(originalKey).build();
return jwtDecoder;
}
public void tester() throws JOSEException {
JwtClaimsSet claims = JwtClaimsSet.builder()
.issuer("self") //Only this for simplicity
.build();
var encoder = jwtEncoder();
//This line throws the exception
String token = encoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
System.out.println(token);
var decoder = jwtDecoder();
Jwt jwt = decoder.decode(token);
System.out.println(jwt.getIssuer());
}
public static void main(String[] args) throws JOSEException {
new EncoderDecoderTest().tester();
}
}
jps has come up with a an explanation to why this doesn't work (AES is not a valid signature algorithm), thanks :-) I guess my question could then be rephrased into: how do I implement a shared secret version of these two encoders/decoders, for example with HMAC using SHA-256?
org.springframework.security.oauth2.jwt.NimbusJwtDecoder
org.springframework.security.oauth2.jwt.NimbusJwtEncoder
I tried (a lot) but have not yet succeeded ;-( Any suggestions for how to fix this problem?
With the input from jps (AES is actually OK for encrypted tokens, but not signed) and Github Copilot I came up with a working solution using HMAC-SHA256:
//Don't hardcode like this for real
public static String secret = "s/4KMb61LOrMYYAn4rfaQYSgr+le5SMrsMzKw8G6bXc=";
public JwtEncoder jwtEncoder() throws JOSEException {
SecretKey key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
JWKSource<SecurityContext> immutableSecret = new ImmutableSecret<SecurityContext>(key);
return new NimbusJwtEncoder(immutableSecret);
}
public JwtDecoder jwtDecoder() {
SecretKey originalKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withSecretKey(originalKey).build();
return jwtDecoder;
}
public void tester() throws JOSEException {
//Create the TOKEN
JwtClaimsSet claims = JwtClaimsSet.builder()
.issuer("https://somewhere.com") //Only this for simplicity
.build();
var encoder = jwtEncoder();
JwsHeader jwsHeader = JwsHeader.with(() -> "HS256").build();
String token = encoder.encode(JwtEncoderParameters.from(jwsHeader, claims)).getTokenValue();
//Decode the TOKEN
var decoder = jwtDecoder();
Jwt jwt = decoder.decode(token);
System.out.println(jwt.getIssuer());
}