Это похоже на стандартный вопрос, но я нигде не смог найти четких указаний.
У меня есть код Java, пытающийся подключиться к серверу с, вероятно, самозаверяющим (или просроченным) сертификатом. Код сообщает о следующей ошибке:
[HttpMethodDirector] I/O exception (javax.net.ssl.SSLHandshakeException) caught
when processing request: sun.security.validator.ValidatorException: PKIX path
building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Насколько я понимаю, я должен использовать keytool и сказать Java, что все в порядке, чтобы разрешить это соединение.
Все инструкции по устранению этой проблемы предполагают, что я полностью владею keytool, например:
создать приватный ключ для сервера и импортировать его в хранилище ключей
Есть ли кто-нибудь, кто мог бы опубликовать подробные инструкции?
Я использую Unix, поэтому лучше использовать bash-скрипт.
Не уверен, что это важно, но код выполняется в jboss.
Ответы:
Здесь у вас есть два основных варианта: добавить самозаверяющий сертификат в хранилище доверенных сертификатов JVM или настроить свой клиент на
Опция 1
Экспортируйте сертификат из вашего браузера и импортируйте его в доверенное хранилище JVM (для создания цепочки доверия):
Вариант 2
Отключить проверку сертификата:
Обратите внимание, что я не рекомендую вариант № 2 вообще . Отключение диспетчера доверия разрушает некоторые части SSL и делает вас уязвимым для атак посредников. Предпочитайте вариант № 1 или, что еще лучше, используйте на сервере «настоящий» сертификат, подписанный известным центром сертификации.
источник
Я преследовал эту проблему до поставщика сертификатов, который не является частью доверенных хостов JVM по умолчанию
JDK 8u74
. Поставщик www.identrust.com , но это не тот домен, к которому я пытался подключиться. Этот домен получил свой сертификат от этого провайдера. См. Будет ли покрытие через корневой каталог доверять списку по умолчанию в JDK / JRE? - прочитайте пару записей. Также посмотрите, какие браузеры и операционные системы поддерживают Let's Encrypt .Итак, чтобы подключиться к интересующему меня домену, у которого был выдан сертификат,
identrust.com
я сделал следующие шаги. По сути, мне нужно было получитьDST Root CA X3
сертификат identrust.com ( ) для доверия со стороны JVM. Я смог сделать это с помощью Apache HttpComponents 4.5 следующим образом:1: Получите сертификат от недоверенного в Инструкции по загрузке цепочки сертификатов . Нажмите на ссылку DST Root CA X3 .
2. Сохраните строку в файл с именем «DST Root CA X3.pem». Обязательно добавьте в файл строки «----- BEGIN CERTIFICATE -----» и «----- END CERTIFICATE -----» в начале и конце файла.
3. Создайте файл хранилища ключей Java cacerts.jks с помощью следующей команды:
4: Скопируйте получившееся хранилище ключей cacerts.jks в каталог ресурсов вашего приложения java / (maven).
5: используйте следующий код, чтобы загрузить этот файл и прикрепить его к Apache 4.5 HttpClient. Это решит проблему для всех доменов, у которых есть сертификаты, выданные
indetrust.com
утилитой Oracle. Включение сертификата в хранилище ключей JRE по умолчанию.Когда проект будет собран, cacerts.jks будет скопирован в путь к классам и загружен оттуда. В данный момент я не тестировал другие ssl-сайты, но если приведенный выше код «цепочек» в этом сертификате, они тоже будут работать, но опять же, я не знаю.
Ссылка: пользовательский контекст SSL и как принять самозаверяющий сертификат с Java HttpsURLConnection?
источник
Apache HttpClient 4.5 поддерживает прием самоподписанных сертификатов:
Это создает фабрику сокетов SSL, которая будет использовать
TrustSelfSignedStrategy
, регистрирует ее с помощью настраиваемого диспетчера соединений, а затем выполняет HTTP GET с использованием этого диспетчера соединений.Я согласен с теми, кто повторяет «не делай этого в производстве», однако есть варианты использования для принятия самозаверяющих сертификатов вне производства; мы используем их в автоматизированных интеграционных тестах, поэтому мы используем SSL (как в рабочей среде), даже если он не работает на производственном оборудовании.
источник
Вместо того, чтобы устанавливать фабрику сокетов по умолчанию (что является IMO - плохая вещь) - это повлияет на текущее соединение, а не на каждое соединение SSL, которое вы пытаетесь открыть:
источник
checkServerTrusted
не реализуете необходимую логику, чтобы фактически доверять сертификату и гарантировать, что ненадежные сертификаты отклонены. Это может быть полезным для чтения: Самый опасный код в мире: проверка SSL-сертификатов в не браузерном программном обеспечении .getAcceptedIssuers()
метод не соответствует спецификации, и это «решение» остается совершенно небезопасным.Существует лучшая альтернатива доверию всем сертификатам: создайте объект,
TrustStore
который определенно доверяет данному сертификату, и используйте его для создания объекта,SSLContext
из которого нужно получитьSSLSocketFactory
значениеHttpsURLConnection
. Вот полный код:Вы также можете загрузить
KeyStore
непосредственно из файла или получить сертификат X.509 из любого надежного источника.Обратите внимание, что с этим кодом сертификаты в
cacerts
не будут использоваться. Этот конкретныйHttpsURLConnection
будет доверять только этот конкретный сертификат.источник
Доверяйте всем SSL-сертификатам: - Вы можете обойти SSL, если хотите провести тестирование на тестовом сервере. Но не используйте этот код для производства.
}
Пожалуйста, вызовите эту функцию в функции onCreate () в Activity или в вашем классе приложения.
Это может быть использовано для залпа в Android.
источник
Принятый ответ - хорошо, но я хотел бы добавить кое-что к этому, поскольку я использовал IntelliJ на Mac и не мог заставить его работать с помощью
JAVA_HOME
переменной пути.Оказывается, Java Home отличался при запуске приложения от IntelliJ.
Чтобы точно определить, где он находится, вы можете просто сделать
System.getProperty("java.home")
так, чтобы именно из него считывались доверенные сертификаты.источник
Если «они» используют самозаверяющий сертификат, они сами должны предпринять шаги, необходимые для обеспечения работоспособности их сервера. В частности, это означает предоставление вам сертификата в автономном режиме надежным способом. Так что заставь их сделать это. Затем вы импортируете это в ваше хранилище доверенных сертификатов, используя keytool, как описано в Справочном руководстве JSSE. Даже не думайте о небезопасном TrustManager, размещенном здесь.
РЕДАКТИРОВАТЬ В интересах семнадцати (!) Downvoters и многочисленных нижеприведенных комментариев, которые явно не читали то, что я здесь написал, это не является иеремией против самозаверяющих сертификатов. Нет ничего плохого в самозаверяющих сертификатах, если они реализованы правильно. Но правильным способом их реализации является безопасная доставка сертификата через автономный процесс, а не через канал без аутентификации, который они будут использовать для аутентификации. Конечно, это очевидно? Это, безусловно, очевидно для каждой организации, работающей в сфере безопасности, в которой я когда-либо работал, от банков с тысячами отделений до моих собственных компаний. Клиентская кодовая база «решение» доверия всемсертификаты, в том числе самозаверяющие сертификаты, подписанные абсолютно кем-либо, или любым арбитражным органом, который создает себя в качестве CA, является ipso factoне является безопасным. Это просто игра в безопасности. Это бессмысленно. У вас частная беседа, защищенная от взлома, ответа и инъекции, с ... кем-то. Кто-нибудь. Человек посередине. Имитатор Кто-нибудь. Вы также можете просто использовать открытый текст.
источник
Это не решение полной проблемы, но у Oracle есть хорошая подробная документация о том, как использовать этот инструмент. Это объясняет, как
https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178
источник
Вместо использования keytool, как предлагается в верхнем комментарии, в RHEL вы можете использовать update-ca-trust, начиная с более новых версий RHEL 6. Вам потребуется сертификат в формате pem. затем
Отредактируйте /etc/pki/ca-trust/source/cert.p11-kit и измените «категория сертификата: другая запись» на «категория сертификата: полномочие». (Или используйте sed, чтобы сделать это в скрипте.) Затем сделайте
Пара предостережений:
update-ca-trust enable
. Это заменит / etc / pki / java / cacerts символической ссылкой, указывающей на / etc / pki / ca-trust / extract / java / cacerts. (Так что, возможно, вы захотите сделать резервную копию первого.)источник
У меня была проблема, что я передавал URL в библиотеку, которая звонила,
url.openConnection();
я адаптировал ответ jon-daniel,Используя этот класс, можно создать новый URL с:
Это имеет то преимущество, что оно локализовано и не заменяет значение по умолчанию
URL.openConnection
.источник