В настоящее время я разрабатываю приложение QuickFIX/J, работающее на Java 17, предназначенное для установки безопасного соединения с внешней стороной с использованием предоставленных сертификатов JKS. При попытке подключения я сталкиваюсь с исключением java.security.cert.CertificateException с сообщением Certificates do not conform to algorithm constraints.
Вот подробности:
Я приложил соответствующие части моей конфигурации 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}
Текстовый список наборов шифров:
В этом посте QuickFIX/J CipherSuites я получил подсказку о том, какие CipherSuites мне нужно сообщить.
@ChristophJohn+ или javax.net.debug=ssl,handshake
или keytool -printcert -sslserver host[:port]
оба декодируют сертификаты за вас (в отличие от дополнительного шага с openssl). И вам нужна (и вы получите) цепочку, которую отправляет другая сторона, но которую она не ожидает.
Спасибо за помощь @ChristophJohn и @dave_thompson_085.
Мне была поставлена задача установить соединение с акцептором по сертификату JKS. Проверив сертификат с помощью команды keytool -list -v -keystore cert.jks -storepass my_password
, я обнаружил, что он использует алгоритм подписи SHA1withRSA
.
Согласно трассировке стека ошибок, этот алгоритм не принимается моей текущей политикой безопасности Java. В идеале решение могло бы заключаться в получении нового сертификата, в котором не используется SHA1withRSA
. Однако из-за ограничений, находящихся вне моего контроля, это было невозможно. Следовательно, я был вынужден найти способ настроить свойства безопасности Java, чтобы разрешить использование этого алгоритма.
Следуя советам из этих двух постов java.security.cert.CertificateException: сертификаты не соответствуют ограничениям алгоритма и проверка ограничений алгоритма Java не удалась для ключа RSA размером 1024 бита, я изменил свой java.security
, чтобы разрешить SHA1withRSA
.
Вы заходили stackoverflow.com/q/14149545/4962355 ? Особенно проверьте, отключены ли алгоритмы для вашего JDK, и используйте команду openssl, чтобы проверить, какую цепочку сертификатов ожидает другая сторона.