I am signing the JWT token using the EC key, Code to create Keys:
ECKey ecKey = new ECKeyGenerator(Curve.SECP256K1)
.keyUse(KeyUse.SIGNATURE)
.keyID(keyId)
.provider(BouncyCastleProviderSingleton.getInstance())
.generate();
After creating a keypair, I created publicKeyJwk
which is hosted in public API for verification of JWT
{
"kty": "EC",
"x": "hZvJ0heaxQxeeBXlSuC-4IPx_UFGeOL5UEYLzLdzfIQ",
"y": "EufmJauadvvkKl7lB7HkzzF9AIVLx4qN9Ih5yf-7eLc",
"crv": "secp256k1"
}
When I try to verify the signature using code verification code :
Provider bc = BouncyCastleProviderSingleton.getInstance();
Security.addProvider(bc);
ECKey ecKey = new ECKey.Builder(Curve.parse("secp256k1"),new Base64URL(x),new Base64URL(y)).build();
ECPublicKey ecPublicKey = ecKey.toECPublicKey();
ECDSAVerifier ecdsaVerifier = new ECDSAVerifier(ecPublicKey);
boolean verify = jwt.verify(ecdsaVerifier);
I am getting this error:
java.security.SignatureException: Curve not supported: java.security.spec.ECParameterSpec@25a6944c
at jdk.crypto.ec/sun.security.ec.ECDSASignature.lambda$engineVerify$0(ECDSASignature.java:493)
at java.base/java.util.Optional.orElseThrow(Optional.java:403)
at jdk.crypto.ec/sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:493)
at java.base/java.security.Signature$Delegate.engineVerify(Signature.java:1422)
at java.base/java.security.Signature.verify(Signature.java:790)
at com.nimbusds.jose.crypto.ECDSAVerifier.verify(ECDSAVerifier.java:201)
at com.nimbusds.jose.JWSObject.verify(JWSObject.java:376)
Runtime: Java: openjdk 17.0.9 2023-10-17
nimbus-jose-jwt:9.37.1
bcprov-jdk18on:1.77
Could someone please provide guidance on what might be wrong here?
As of Java 161, there is no built-in support for secp256k1, so a third-party provider is required, e.g. BouncyCastle, as you already do for key generation.
For verification, the following must be added to your code:
import com.nimbusds.jose.crypto.bc.BouncyCastleProviderSingleton;
...
ECDSAVerifier ecdsaVerifier = new ECDSAVerifier(ecPublicKey);
ecdsaVerifier.getJCAContext().setProvider(BouncyCastleProviderSingleton.getInstance()); // add
see also here.
1 secp256k1 is already disabled by default in Java 15, but can be enabled.