我正在使用 EC 密钥签署 JWT 令牌, 创建密钥的代码:
ECKey ecKey = new ECKeyGenerator(Curve.SECP256K1)
.keyUse(KeyUse.SIGNATURE)
.keyID(keyId)
.provider(BouncyCastleProviderSingleton.getInstance())
.generate();
创建密钥对后,我创建了
publicKeyJwk
,它托管在公共 API 中,用于验证 JWT
{
"kty": "EC",
"x": "hZvJ0heaxQxeeBXlSuC-4IPx_UFGeOL5UEYLzLdzfIQ",
"y": "EufmJauadvvkKl7lB7HkzzF9AIVLx4qN9Ih5yf-7eLc",
"crv": "secp256k1"
}
当我尝试使用代码验证码验证签名时:
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);
我收到此错误:
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)
运行时: Java:openjdk 17.0.9 2023-10-17
nimbus-何塞-jwt:9.37.1
bcprov-jdk18on:1.77
有人可以就这里可能出现的问题提供指导吗?
从 Java 17 开始,没有对 secp256k1 的内置支持,因此需要第三方提供程序,例如BouncyCastle,就像您已经为密钥生成所做的那样。
为了进行验证,必须将以下内容添加到您的代码中:
import com.nimbusds.jose.crypto.bc.BouncyCastleProviderSingleton;
...
ECDSAVerifier ecdsaVerifier = new ECDSAVerifier(ecPublicKey);
ecdsaVerifier.getJCAContext().setProvider(BouncyCastleProviderSingleton.getInstance()); // add
另请参阅此处。