Почему я получаю исключение javax.net.ssl.SSLPeerUnverifiedException: одноранговый узел не аутентифицирован только в рабочей среде?
У меня есть приложение Grails 1.3.7, которое делает вызов HTTPS API третьей стороне, использующей Apache HttpClient. У стороннего URL, который я нажимаю, есть действительный сертификат. Я создаю и выполняю свой запрос так:
HttpClient client = new DefaultHttpClient()
List<BasicNameValuePair> queryParams = new ArrayList<BasicNameValuePair>()
queryParams.add(new BasicNameValuePair("a_parameter", "a_parameter_value"))
URI uri = URIUtils.createURI("https", "third.party.address", 443, "/some/url/for/us", URLEncodedUtils.format(queryParams, "UTF-8"), null)
HttpGet httpGet = new HttpGet(uri)
try {
log.debug "Sending request to ${uri}"
return client.execute(httpGet)
} catch(HttpException e) {
log.error "HttpException during location lookup request: ${e}"
return
} catch(IOException e) {
log.error "IOException during location lookup request: ${e}"
return
}
Это работает нормально, когда я запускаю свой проект в режиме разработки. Я также могу напрямую вызывать тот же URL из curl и моего браузера без ошибок. Однако, как только мой проект встроен в файл war и помещен в экземпляр tomcat, для которого определено хранилище сертификатов / ключей, чтобы клиенты могли подключаться к США с помощью https, мои запросы начинают сбой со следующей исключительной ситуацией IOException:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
Я пытаюсь выяснить причину неудачи здесь.
Почему выполнение запроса https из curl или моего режима разработки отличается от выполнения запроса https из настроенного https экземпляра tomcat?
Экземпляр tomcat не является общедоступным, но при подключении к нему через браузер проблем с сертификатом не возникает (chrome говорит, что сертификат в порядке, как и подробный запрос скручивания).
Я ни в коем случае не являюсь экспертом в https/ssl, поэтому мне нужна помощь, чтобы объяснить, что не так, почему это не так и как я могу это исправить. Я могу предоставить любую другую необходимую информацию.
--- Обновление --- Я включил javax.net.debug
как предложено ниже, и вывод включает в себя следующую ошибку:
java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be\
non-empty
Мой поиск в Google заставил меня думать, что эта проблема, потому что я использую следующую опцию java при запуске tomcat:
-Djavax.net.ssl.trustStore=/path/to/tomcat/conf/myStore.jks
Если это правда, как я могу добавить вещи, которые мне нужны, в myStore.jks и не переопределять значения по умолчанию, чтобы все были довольны?
2 ответа
Решение для меня закончилось тем, что мы переопределяли хранилище java trust по умолчанию своим собственным с java opt. Это привело к тому, что сертификат, отправленный третьей стороной, оказался недействительным, поскольку в нашем myStore.jks не было корневых сертификатов по умолчанию.
Добавив наш самозаверяющий сертификат в java по умолчанию (/lib/security/cacerts) и удалив опцию java, все было хорошо.
Альтернативой было бы добавить все в хранилище java по умолчанию в ваше хранилище и по-прежнему использовать java opt. В зависимости от того, что вы находите более приемлемым для вашей ситуации.
Я видел эту ошибку очень много раз. Я использовал следующую утилиту, чтобы получить сертификат с сайта, который использует SSL. Зайдите сюда и возьмите InstallCert. Скомпилируйте и запустите эту утилиту. Вы можете использовать файл, сгенерированный этой утилитой, в качестве хранилища ключей.