QuickFIX/J - 证书不符合算法约束

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

我目前正在开发一个在 Java 17 上运行的 QuickFIX/J 应用程序,旨在使用提供的 JKS 证书与外部方建立安全连接。尝试连接时,我遇到 java.security.cert.CertificateException 并显示消息

Certificates do not conform to algorithm constraints.

详情如下:

  • QuickFIX/J 版本:2.3.1
  • Java版本:17
  • 错误消息:java.security.cert.CertificateException:证书不符合算法约束

我已附上 QuickFIX/J 配置的相关部分和错误的堆栈跟踪。任何人都可以提供有关如何解决此证书问题的建议或建议任何可能防止此错误的配置吗?

非常感谢您提供的任何帮助!

我的 QuickFIX/J 配置

ConnectionType=initiator
SocketConnectHost=my_ip
SocketConnectPort=my_port
SocketUseSSL=Y
CipherSuites=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
EnabledProtocols=TLSv1.2
SocketKeyStore=/path/cert.jks
SocketKeyStorePassword=my_passowrd
SocketTrustStore=/path-trust/truststore.jks
SocketTrustStorePassword=my_password

我的错误

javax.net.ssl|ERROR|A2|NioProcessor-2|2024-05-08 16:28:46.528 BRT|TransportContext.java:370|Fatal (UNSUPPORTED_CERTIFICATE): Certificates do not conform to algorithm constraints (
"throwable" : {
  java.security.cert.CertificateException: Certificates do not conform to algorithm constraints
    at java.base/sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:1573)
    at java.base/sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1538)
    at java.base/sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:1456)
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:632)
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473)
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369)
    at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1277)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1264)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1209)
    at org.apache.mina.filter.ssl.SslHandler.doTasks(SslHandler.java:816)
    at org.apache.mina.filter.ssl.SslHandler.handshake(SslHandler.java:591)
    at org.apache.mina.filter.ssl.SslHandler.messageReceived(SslHandler.java:356)
    at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:517)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128)
    at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:122)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:643)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1224)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1213)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683)
    at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:840)
  Caused by: java.security.cert.CertPathValidatorException: Algorithm constraints check failed on signature algorithm: SHA1withRSA
    at java.base/sun.security.provider.certpath.AlgorithmChecker.check(AlgorithmChecker.java:237)
    at java.base/sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:1569)
    ... 30 more}

对接方的要求

enter image description here

enter image description here

以文本方式列出密码套件:

  • TLS_ECDHE_RSA_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_AES_128_CBC_SHA256

在这篇文章 QuickFIX/J CipherSuites 中,我收到了有关我需要通知哪些 CipherSuites 的提示。

java quickfixj
1个回答
0
投票

感谢@ChristophJohn 和@dave_thompson_085 的帮助

澄清我的问题

我的任务是使用 JKS 证书与接受者建立连接。使用命令

keytool -list -v -keystore cert.jks -storepass my_password
检查证书后,我发现它采用了
SHA1withRSA
签名算法。

根据错误堆栈跟踪,我当前的 Java 安全策略不接受该算法。理想情况下,解决方案将涉及获取不使用 SHA1withRSA 的新证书。然而,由于我无法控制的限制,这是不可行的。因此,我不得不找到一种方法来调整我的 Java 安全属性以允许使用该算法。

配置挑战
java.security.properties

我使用企业 Java 映像在 Kubernetes 环境中运行我的应用程序。尽管多次尝试,我还是无法成功覆盖 java.security.properties 文件。

作为解决方法,我实现了一个运行时解决方案,其中涉及直接从代码动态修改 Java 安全设置。具体来说,我创建了两个在运行时传递的

List<String>
变量。这些列表用于以编程方式调整
jdk.certpath.disabledAlgorithms
属性中
jdk.tls.disabledAlgorithms
java.security.Security
中的条目。

对于这种特殊情况,我需要启用

SHA1withRSA
,它是禁用算法列表中找到的字符串
SHA1,
的一部分。以下是修改
jdk.certpath.disabledAlgorithms
属性的方法:

修改前:

  • MD2, SHA1, MD5, DSA, RSA keySize < 2048

修改后:

  • MD2, MD5, DSA, RSA keySize < 2048

此调整对于建立必要的连接至关重要,同时又不会过度损害周围基础设施的安全。

解决方法代码(谨慎使用)

以下配置和代码片段演示了我如何在运行时调整 JVM 的安全设置以适应必要的算法。这是一种解决方法,应谨慎处理,因为它会削弱 JVM 的安全立场。

应用程序属性

以下是我在

application.properties
文件中为开发和生产环境设置属性的方法:

# Default settings (effective in production)
app.list.jdk.certpath.disabledAlgorithms=empty,
app.list.jdk.tls.disabledAlgorithms=empty,

Kubernetes 部署的 YAML 配置

此 YAML 配置片段用于将环境变量传递给应用程序,指定要从禁用列表中删除哪些算法:

# Removing 'SHA1, '
- name: "app.list.jdk.certpath.disabledAlgorithms"
  value: "SHA1\\, ,"

Java方法修改安全设置

此 Java 方法在应用程序启动时执行,以根据提供的配置动态调整安全属性:

@ConfigProperty(name = "app.list.jdk.certpath.disabledAlgorithms")
List<String> appListJdkCertPathDisableAlgorithms;

@ConfigProperty(name = "app.list.jdk.tls.disabledAlgorithms")
List<String> appListJdkTlsDisableAlgorithms;

private void removeDisableAlgorithms() {
    LOG.info("Original Certpath and TLS configuration");
    LOG.info("Certpath disabled algorithms: " + Security.getProperty("jdk.certpath.disabledAlgorithms"));
    LOG.info("TLS disabled algorithms: " + Security.getProperty("jdk.tls.disabledAlgorithms"));
    LOG.info("Configured removals for Certpath: " + appListJdkCertPathDisableAlgorithms);
    LOG.info("Configured removals for TLS: " + appListJdkTlsDisableAlgorithms);

    String jdkCertPathDisabledAlgorithms = Security.getProperty("jdk.certpath.disabledAlgorithms");
    for (String item : appListJdkCertPathDisableAlgorithms) {
        jdkCertPathDisabledAlgorithms = jdkCertPathDisabledAlgorithms.replace(item, "");
    }
    Security.setProperty("jdk.certpath.disabledAlgorithms", jdkCertPathDisabledAlgorithms);

    String jdkTlsDisabledAlgorithms = Security.getProperty("jdk.tls.disabledAlgorithms");
    for (String item : appListJdkTlsDisableAlgorithms) {
        jdkTlsDisabledAlgorithms = jdkTlsDisabledAlgorithms.replace(item, "");
    }
    Security.setProperty("jdk.tls.disabledAlgorithms", jdkTlsDisabledAlgorithms);

    LOG.info("Updated Certpath and TLS configuration");
    LOG.info("Certpath disabled algorithms: " + Security.getProperty("jdk.certpath.disabledAlgorithms"));
    LOG.info("TLS disabled algorithms: " + Security.getProperty("jdk.tls.disabledAlgorithms"));
}

注意事项和最后的想法

此方法会操纵 JVM 安全设置,因此应极其谨慎地使用,尤其是在生产环境中。在考虑此类修改时,请务必评估潜在风险并咨询安全专家。

© www.soinside.com 2019 - 2024. All rights reserved.