【问题标题】:Bug in Keycloak package? ( ECDSA KeyFactory not available )Keycloak 包中的错误? (ECDSA KeyFactory 不可用)
【发布时间】:2022-01-19 16:09:06
【问题描述】:

运行我的 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 func 仍然尝试使用 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 运行时(确切版本、分发器和操作系统)?众所周知,Linux 上较旧的 OpenJDK 版本(例如 OpenJDK 8)存在 ECDSA 问题。
  • 我使用的是 openJDK 11.0.3

标签: java security oauth-2.0 keycloak java.security


【解决方案1】:

您的主要问题是您忘记告诉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());

【讨论】:

  • 声明 '''KeyFactory kf = KeyFactory.getInstance("ECDSA")''' 的行不是来自我的方法,而是来自调用createECPublickey() 当访问请求来自客户端时,因此我无法传递 BC 对象并以告诉 Keyfactory 从 BC 获取 ECDSA 的方式编辑该行,也无法添加行来添加提供程序。
  • @Ryuu 然后在 Keycloak 项目中打开一个关于此错误的问题。同时,您可以使用变通方法手动将 BouncyCastle 添加到整个 JRE。将 security.provider.N = org.bouncycastle.jce.provider.BouncyCastleProvider 添加到 JRE 中的文件 java.security 文件中。这不是使用 BouncyCastle 的推荐方式,但至少它有效。
猜你喜欢
  • 1970-01-01
  • 2014-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
  • 2019-05-08
  • 1970-01-01
  • 2022-09-28
相关资源
最近更新 更多