Keycloak 包中的错误? ( ECDSA KeyFactory 不可用)

问题描述 投票:0回答:2

运行我的 keycloak 应用程序时,出现以下错误:

java.security.NoSuchAlgorithmException: ECDSA KeyFactory not available
    at java.base/java.security.KeyFactory.<init>(KeyFactory.java:138) ~[na:na]
    at java.base/java.security.KeyFactory.getInstance(KeyFactory.java:183) ~[na:na]
    at org.keycloak.jose.jwk.JWKParser.createECPublicKey(JWKParser.java:107) ~[keycloak-core-15.0.2.jar:15.0.2]
    ... 61 common frames omitted

经过一番挖掘,发现 KeyFactory 无法将“ECDSA”确定为算法,因此我应该使用“EC”算法来生成公钥。

但是如果 KeyFactory 不支持“ECDSA”作为算法,为什么 Keycloak-15.0.2 JWKParser 类的 createECPublicKey 函数仍然尝试使用 ECDSA 生成公钥?

try {
            ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(name);
            ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());
            ECPoint point = new ECPoint(x, y);
            ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);

            KeyFactory kf = KeyFactory.getInstance("ECDSA");
            return kf.generatePublic(pubKeySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

这是一个错误吗?还是我完全错过了一些东西?

java security oauth-2.0 keycloak java.security
2个回答
2
投票

您的主要问题是您忘记告诉

KeyFactory.getInstance
ECDSA
来自 BouncyCastle 提供商。

你添加这个,

KeyFactory.getInstance("ECDSA");
就会起作用:

public static final Provider BC = new BouncyCastleProvider();

...

public static void myMethod() {
    ...
    KeyFactory kf = KeyFactory.getInstance("ECDSA", BC);
}

或者,您可以将 BouncyCastleProvider 添加到您的提供商列表中:

Security.addProvider(new BouncyCastleProvider());

0
投票

如果有人在完成建议的答案后仍然遇到困难:

即使在执行“Security.addProvider(new BouncyCastleProvider());”时,我在 docker 容器和 osgi BundleActivator 中运行此代码时也遇到同样的问题。就我而言,出现问题是因为我在 Bundleactivator 中添加了 Provider,如下所示:

        Security.addProvider(new BouncyCastleProvider());

但是在构建我的项目后,它尝试再次执行addProvider,但它没有执行任何操作,因为从docker启动捆绑激活中已经存在一个Provider,但旧的Provider似乎已经过时了。对此进行调试,我发现“无法加载类 'org.bouncycastle.jcajce.provider.ametry.ec.KeyFactorySpi$ECDSA',因为 myBundle 的捆绑连接不再有效。”调用 KeyFactory.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME) 后。

所以这种情况下的解决方案就是删除并重新添加它:

public void start(final BundleContext bundleContext) throws Exception {
    // removing the initial BouncyCastleProvider to cleanly re-add it avoids the "ECDSA Keyfactory not available" error
    if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) != null) {
        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
    }
    // add BouncyCastle as security provider, since it is required by the keycloak filter adapter
    Security.addProvider(new BouncyCastleProvider());
}
© www.soinside.com 2019 - 2024. All rights reserved.