"не удалось найти допустимый путь сертификации для запрошенной цели", но браузер говорит об этом

Я разрабатываю приложение Java, которое подключается к SOAP-сервисам, открытым на https://ut.eurodw.eu/ (тестовая среда для Европейского Datawarehouse). Я работаю над своей машиной разработки, недавно переформатированной с Windows 8.1. Сегодня я попытался отправить им запрос на создание через SOAP из моей программы и получил эту ошибку:

Caused by: javax.xml.ws.WebServiceException: Could not send Message.
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:146)
    at com.sun.proxy.$Proxy110.createDeal(Unknown Source)
    at it.csttech.edwin.services.spring.EdwinServiceImpl.createDeal(EdwinServiceImpl.java:102)
    at it.csttech.edwin.consumercredit.data.managers.spring.DealManagerImpl.createEdCode(DealManagerImpl.java:319)
    ... 77 more
Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://ut.eurodw.eu/edservices/2.2/DealService.svc: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1339)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1323)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:628)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
    ... 80 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:174)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1283)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1239)
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:201)
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1296)
    ... 90 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
    ... 108 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 114 more

Как вы можете видеть, щелкнув ссылку выше, что нет самозаверяющего сертификата, но выпущенный общедоступным CA GoDaddy, который распознается моим браузером Firefox. Моя версия Java 1.7.0_60-b19. Это будет плохая идея, чтобы изменить код, чтобы разрешить небезопасные SSL-соединения.

Вместо этого я хотел бы убедиться, что сертификат eurodw находится в хранилище доверия. Как я могу это проверить? И как мне импортировать новый сертификат?

PS В настоящий момент я не могу протестировать сервер, на котором развертывается окончательное приложение: я могу использовать только свою собственную установку Tomcat.

Ответ 1

Различные сертификаты можно найти в следующем хранилище ключей:

% JAVA_HOME%/JRE/Library/безопасность/cacerts

Если вы хотите перечислить доверенные сертификаты:

keytool -list -keystore %JAVA_HOME%/jre/lib/security/cacerts

Пароль для выбора необязателен.

Если вы хотите добавить запись:

Сначала экспортируйте сертификат для импорта, скажем, это будет c:\cert.crt. Лучший способ сделать это - использовать firefox, щелкнуть правой кнопкой мыши на снимке блокировки в URL-адресе, и через несколько кликов у вас есть функция экспорта.

Затем введите:

keytool -import -alias my-cert -file c:\cert.crt -keystore %JAVA_HOME%/jre/lib/security/cacerts

Пароль: changeit

Псевдоним, являющийся пользовательской меткой, выбирает ее с умом, чтобы помнить, если вам это нужно в один прекрасный день, что это было.

Со всем этим вы должны быть в состоянии доверять сертификату и иметь все, что работает снова.

Ответ 2

Если ваш хост находится за брандмауэром/прокси, используйте следующую команду в cmd:

keytool -J-Dhttps.proxyHost=<proxy_hostname> -J-Dhttps.proxyPort=<proxy_port> -printcert -rfc -sslserver <remote_host_name:remote_ssl_port>

Замените <proxy_hostname> и <proxy_port> на настроенный прокси-сервер HTTP. Замените <remote_host_name:remote_ssl_port> одним из удаленных хостов (в основном, url) и порта, имеющих проблему с сертификацией.

Возьмите последний напечатанный контент сертификата и скопируйте его (также скопируйте начало и конец сертификата). Вставьте его в текстовый файл и дайте ему расширение .crt. Теперь импортируйте этот сертификат в cacerts с помощью команды java keytool, и он должен работать.

keytool -importcert -file <filename>.crt -alias randomaliasname -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit