Редактировать: - Попытался отформатировать вопрос и принял ответ более презентабельным способом в моем блоге
Вот оригинальная проблема.
Я получаю эту ошибку:
подробное сообщение sun.security.validator.ValidatorException: не удалось построить путь PKIX:
sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации к запрошенной целипричиной javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: сбой построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации для запрошенной цели
Я использую Tomcat 6 в качестве веб-сервера. У меня есть два веб-приложения HTTPS, установленные на разных Tomcats на разных портах, но на одной машине. Скажите App1(port 8443)
и App2(port 443)
. App1
подключается к App2
. Когда App1
подключается к App2
я получаю вышеуказанную ошибку. Я знаю, что это очень распространенная ошибка, поэтому сталкивался со многими решениями на разных форумах и сайтах. У меня есть запись ниже в server.xml
обоих Tomcats:
keystoreFile="c:/.keystore"
keystorePass="changeit"
На каждом сайте указана одна и та же причина, по которой сертификат, предоставленный app2, отсутствует в доверенном хранилище app1 jvm. Кажется, это также верно, когда я пытался перейти по тому же URL-адресу в браузере IE, он работает (с потеплением. Существует проблема с этим сертификатом безопасности веб-сайта. Здесь я говорю, перейдите на этот веб-сайт). Но когда Java-клиент использует тот же URL-адрес (в моем случае), я получаю вышеуказанную ошибку. Поэтому, чтобы положить его в доверенное хранилище, я попробовал эти три варианта:
Опция 1
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Option2 Настройка ниже в переменной среды
CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Option3 Настройка ниже в переменной среды
JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Но ничего не сработало.
Наконец, сработало выполнение подхода Java, предложенного в разделе Как обрабатывать недействительные сертификаты SSL с помощью Apache HttpClient? по Паскалю Thivent, т.е. выполнение программы InstallCert.
Но этот подход хорош для установки devbox, но я не могу использовать его в производственной среде.
Мне интересно, почему три упомянутых выше подхода не сработали, когда я упомянул одинаковые значения в server.xml
сервера app2
и одинаковые значения в хранилище доверенных сертификатов, установив
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
в программе app1
.
Для получения дополнительной информации вот как я делаю соединение:
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
if (conn instanceof HttpsURLConnection) {
HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();
conn1.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
reply.load(conn1.getInputStream());