Следует отметить, что ответы на этот вопрос не более того, чем задано: они позволяют игнорировать ошибку, но не устраняют основную проблему (это немного похоже на извлечение батарей из дымовой пожарной сигнализации вместо тушения пожара. ). Сертификаты предназначены для обеспечения безопасности соединения SSL / TLS, игнорирование этих ошибок создает уязвимость для атаки MITM. Используйте тестовые сертификаты вместо игнорирования ошибки.
«как вынуть батарейки из дымовой пожарной сигнализации». Вы можете дать другим разработчикам возможность сомневаться в своих силах и предположить, что они знают, что делают. Возможно, мотивом для этого вопроса является локальное тестирование, и ОП желает провести быстрый тест, не проходя ужасное количество шаблонов Java, необходимых для настройки даже простой среды SSL. Может быть, кто-нибудь сможет просто ответить на этот вопрос, не вдаваясь в лекцию «Священнее тебя».
Майк
Т.е. на внутреннем сервере JIRA нашей компании есть некий «сертификат на основе политики безопасности Windows», который действителен на компьютерах с Windows, включенных в домен, и недействителен на других. Я не могу контролировать эту политику и все еще хочу вызвать JIRA REST API.
odiszapc 05
1
@Bruno Невозможность отключить детекторы дыма на 30-60 минут при тушении небольшого кухонного пожара показывает безумное отсутствие понимания закономерностей использования некоторых официальных лиц в какой-то момент, что я чувствую граничащие с преступностью. Доказательством этого является то, что существует понятие «вынуть батарейки из дымовой сигнализации». Я чувствую примерно такой же уровень гнева по поводу необходимости получать сертификаты для работы для простого теста, который, как я знаю, не имеет последствий для безопасности. Наличие этого вопроса доказывает это.
Bill K
Ответы:
84
Вам нужно создать SSLContext с вашим собственным TrustManager и создать схему HTTPS, используя этот контекст. Вот код,
SSLContext sslContext =SSLContext.getInstance("SSL");// set up a TrustManager that trusts everything
sslContext.init(null,newTrustManager[]{new X509TrustManager(){public X509Certificate[] getAcceptedIssuers(){System.out.println("getAcceptedIssuers =============");returnnull;}publicvoid checkClientTrusted(X509Certificate[] certs,String authType){System.out.println("checkClientTrusted =============");}publicvoid checkServerTrusted(X509Certificate[] certs,String authType){System.out.println("checkServerTrusted =============");}}},newSecureRandom());SSLSocketFactory sf =newSSLSocketFactory(sslContext);Scheme httpsScheme =newScheme("https",443, sf);SchemeRegistry schemeRegistry =newSchemeRegistry();
schemeRegistry.register(httpsScheme);// apache HttpClient version >4.2 should use BasicClientConnectionManagerClientConnectionManager cm =newSingleClientConnManager(schemeRegistry);HttpClient httpClient =newDefaultHttpClient(cm);
Допустим, я не хочу покупать действующий сертификат SSL для своего сайта и просто хочу его использовать, этот фрагмент кода может помочь? Почему я не вижу части, в которой нужен URL-адрес или обработка исключений?
Viet
19
Хм, он говорит мне, что «новый SSLSocketFactory (ssslCont)» ожидает хранилище ключей, а не SSLContext. Я что-то упускаю?
MSpeed 05
2
Я получаю сообщение об ошибке, что X509TrustManager не может быть преобразован в TrustManager.
МВт.
2
Убедитесь, что вы импортируете правильные пакеты, то есть из org.apache.http.
warden
2
Кто-нибудь знает, как все это скинуть с помощью HttpClientBuilder?
Али
112
Все остальные ответы либо устарели, либо не работали для HttpClient 4.3.
Вот способ разрешить все имена хостов при создании http-клиента.
Спасибо за ответ, я хотел бы знать, из какого пакета HttpsClients, который я использую в компиляции Android ("org.apache.httpcomponents: httpclient: 4.3.4"), но этот класс не отображается.
Хуан Саравиа
1
Это пакет org.apache.http.impl.client.HttpClients.
erversteeg
14
Это работает с несоответствием имени хоста (я предполагаю), но это не работает, если сертификат не подписан доверенным центром.
twm
1
@twm, поэтому он говорит, что "разрешает все имена хостов", проблемы с доверием требуют другой конфигурации.
eis
1
@eis, я указывал, что в некоторых случаях этот ответ относится к исходному вопросу, но не в других.
twm
43
Просто нужно было сделать это с более новым HttpClient 4.5, и похоже, что они устарели с некоторых вещей, начиная с 4.4, поэтому вот фрагмент, который работает для меня и использует самый последний API:
Спасибо! Просто измените TrustAllStrategy.INSTANCEс TrustSelfSignedStrategy.INSTANCEтаким ответом.
Перси Вега
У меня это не сработало. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: сбой построения пути PKIX: sun.security. provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации для запрошенной цели
ggb667
Спасибо, работал у меня без проблем.
Санджай Джейн,
31
Просто для записи, есть гораздо более простой способ сделать то же самое с HttpClient 4.1.
SSLSocketFactory sslsf =newSSLSocketFactory(newTrustStrategy(){publicboolean isTrusted(final X509Certificate[] chain,String authType)throwsCertificateException{// Oh, I am easy...returntrue;}});
Для HttpClient 4.4 и более поздних версий вы должны сделать это - и, возможно, также потребуется создать SSLConnectionSocketFactoryusing SSLContextthis и определить это в файле Registry<ConnectionSocketFactory>, если вы собираетесь создать файл PoolingHttpClientConnectionManager. Другие ответы более популярны, но не работают в HttpClient 4.4.
Thomas W
1
Точно так же работает с httpclient-4.3.5.jar.
Harald
18
Для Apache HttpClient 4.4:
HttpClientBuilder b =HttpClientBuilder.create();SSLContext sslContext =newSSLContextBuilder().loadTrustMaterial(null,newTrustStrategy(){publicboolean isTrusted(X509Certificate[] arg0,String arg1)throwsCertificateException{returntrue;}}).build();
b.setSslcontext( sslContext);// or SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weakenHostnameVerifier hostnameVerifier =SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;SSLConnectionSocketFactory sslSocketFactory =newSSLConnectionSocketFactory(sslContext, hostnameVerifier);Registry<ConnectionSocketFactory> socketFactoryRegistry =RegistryBuilder.<ConnectionSocketFactory>create().register("http",PlainConnectionSocketFactory.getSocketFactory()).register("https", sslSocketFactory).build();// allows multi-threaded usePoolingHttpClientConnectionManager connMgr =newPoolingHttpClientConnectionManager( socketFactoryRegistry);
b.setConnectionManager( connMgr);HttpClient client = b.build();
Это извлечено из нашей реальной рабочей реализации.
Другие ответы популярны, но для HttpClient 4.4 они не работают. Я потратил часы на попытки и исчерпывающие возможности, но, похоже, в 4.4 произошли чрезвычайно серьезные изменения и перемещение API.
Метод sf.setHostnameVerifier устарел с версии 4.1. Альтернативой является использование одного из конструкторов. Например:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Kaliatech 01
Это было очень полезно, когда мне приходилось иметь дело с устаревшим кодом.
DuncanSungWKim
9
Мы используем HTTPClient 4.3.5, и мы попробовали почти все решения, существующие в stackoverflow, но ничего. Подумав и выяснив проблему, мы приходим к следующему коду, который отлично работает, просто добавьте его перед созданием экземпляра HttpClient.
какой-то метод для вызова при отправке почтовых запросов ....
Вы можете добиться того же, просто делаяsf.setHostnameVerifier(new AllowAllHostnameVerifier());
Дэн Дайер
7
Sf.setHostnameVerifier устарел с версии 4.1. Альтернативой является использование одного из конструкторов. Например:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Kaliatech 01
4
DefaultHttpClient httpclient =newDefaultHttpClient();SSLContext sslContext;try{
sslContext =SSLContext.getInstance("SSL");// set up a TrustManager that trusts everythingtry{
sslContext.init(null,newTrustManager[]{new X509TrustManager(){public X509Certificate[] getAcceptedIssuers(){
log.debug("getAcceptedIssuers =============");returnnull;}publicvoid checkClientTrusted(
X509Certificate[] certs,String authType){
log.debug("checkClientTrusted =============");}publicvoid checkServerTrusted(
X509Certificate[] certs,String authType){
log.debug("checkServerTrusted =============");}}},newSecureRandom());}catch(KeyManagementException e){}SSLSocketFactory ssf =newSSLSocketFactory(sslContext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);ClientConnectionManager ccm =this.httpclient.getConnectionManager();SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(newScheme("https",443, ssf));}catch(Exception e){
log.error(e.getMessage(),e);}
Спасибо за обновленный ответ, я наградил нового парня за «гостеприимство», но я просто хотел получить обновленные ответы для всех!
1
@feelingunwelcome, конечно. Я тоже проголосовал за него :-)
Тарун Лалвани
2
полная рабочая версия для Apache HttpClient 4.1.3 (на основе приведенного выше кода Олега, но в моей системе по-прежнему требовался allow_all_hostname_verifier):
Обратите внимание, что я повторно выбрасываю все исключения, потому что на самом деле я мало что могу сделать, если что-то из этого выйдет из строя в реальной системе!
Если вы столкнулись с этой проблемой при использовании AmazonS3Client, который включает Apache HttpClient 4.1, вам просто нужно определить такое системное свойство, чтобы упростить проверку сертификата SSL:
Если вы используете Apache httpClient 4.5.x, попробуйте следующее:
publicstaticvoid main(String... args){try(CloseableHttpClient httpclient = createAcceptSelfSignedCertificateClient()){HttpGet httpget =newHttpGet("https://example.com");System.out.println("Executing request "+ httpget.getRequestLine());
httpclient.execute(httpget);System.out.println("----------------------------------------");}catch(NoSuchAlgorithmException|KeyStoreException|KeyManagementException|IOException e){thrownewRuntimeException(e);}}privatestaticCloseableHttpClient createAcceptSelfSignedCertificateClient()throwsKeyManagementException,NoSuchAlgorithmException,KeyStoreException{// use the TrustSelfSignedStrategy to allow Self Signed CertificatesSSLContext sslContext =SSLContextBuilder.create().loadTrustMaterial(newTrustSelfSignedStrategy()).build();// we can optionally disable hostname verification. // if you don't want to further weaken the security, you don't have to include this.HostnameVerifier allowAllHosts =newNoopHostnameVerifier();// create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy// and allow all hosts verifier.SSLConnectionSocketFactory connectionFactory =newSSLConnectionSocketFactory(sslContext, allowAllHosts);// finally create the HttpClient using HttpClient factory methods and assign the ssl socket factoryreturnHttpClients.custom().setSSLSocketFactory(connectionFactory).build();}
Ответы:
Вам нужно создать SSLContext с вашим собственным TrustManager и создать схему HTTPS, используя этот контекст. Вот код,
источник
HttpClientBuilder
?Все остальные ответы либо устарели, либо не работали для HttpClient 4.3.
Вот способ разрешить все имена хостов при создании http-клиента.
Или, если вы используете версию 4.4 или новее, обновленный вызов выглядит так:
источник
Просто нужно было сделать это с более новым HttpClient 4.5, и похоже, что они устарели с некоторых вещей, начиная с 4.4, поэтому вот фрагмент, который работает для меня и использует самый последний API:
источник
Apache HttpClient 4.5.5
Устаревший API не использовался.
Простой проверяемый тестовый пример:
источник
TrustAllStrategy.INSTANCE
сTrustSelfSignedStrategy.INSTANCE
таким ответом.Просто для записи, есть гораздо более простой способ сделать то же самое с HttpClient 4.1.
источник
new SSLSocketFactory((chain, authType) -> true);
Для справки, протестировано с httpclient 4.3.6 и совместимо с Executor fluent api:
источник
SSLConnectionSocketFactory
usingSSLContext
this и определить это в файлеRegistry<ConnectionSocketFactory>
, если вы собираетесь создать файлPoolingHttpClientConnectionManager
. Другие ответы более популярны, но не работают в HttpClient 4.4.Для Apache HttpClient 4.4:
Это извлечено из нашей реальной рабочей реализации.
Другие ответы популярны, но для HttpClient 4.4 они не работают. Я потратил часы на попытки и исчерпывающие возможности, но, похоже, в 4.4 произошли чрезвычайно серьезные изменения и перемещение API.
См. Также чуть более полное объяснение по адресу: http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/
Надеюсь, это поможет!
источник
Если все, что вам нужно сделать, это избавиться от ошибок неверного имени хоста, вы можете просто сделать:
источник
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Мы используем HTTPClient 4.3.5, и мы попробовали почти все решения, существующие в stackoverflow, но ничего. Подумав и выяснив проблему, мы приходим к следующему коду, который отлично работает, просто добавьте его перед созданием экземпляра HttpClient.
источник
В fluent 4.5.2 мне пришлось внести следующую модификацию, чтобы она работала.
источник
Вот как я это сделал -
Инициализация DefaultHTTPClient -
Фабрика фиктивных SSL -
Если за прокси, нужно сделать это -
источник
В дополнение к ответу ZZ Coder было бы неплохо переопределить hostnameverifier.
источник
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
источник
Чтобы принять все сертификаты в HttpClient 4.4.x, вы можете использовать следующий лайнер при создании httpClient:
источник
Протестировано с HttpClient 4.5.5 с Fluent API
источник
Ниже код работает с
4.5.5
Вывод из кода
Вывод в браузере
Используемый помпон ниже
источник
полная рабочая версия для Apache HttpClient 4.1.3 (на основе приведенного выше кода Олега, но в моей системе по-прежнему требовался allow_all_hostname_verifier):
Обратите внимание, что я повторно выбрасываю все исключения, потому что на самом деле я мало что могу сделать, если что-то из этого выйдет из строя в реальной системе!
источник
Если вы используете свободный API , вам необходимо настроить его через
Executor
:... где
sslContext
создается SSLContext, как показано в ответе ZZ Coder .После этого вы можете выполнять свои http-запросы как:
Примечание: протестировано с HttpClient 4.2
источник
Протестировано с 4.3.3
}
источник
Проверено на 4.5.4:
источник
Если вы столкнулись с этой проблемой при использовании AmazonS3Client, который включает Apache HttpClient 4.1, вам просто нужно определить такое системное свойство, чтобы упростить проверку сертификата SSL:
-Dcom.amazonaws.sdk.disableCertChecking = верно
Шалость удалась
источник
fwiw, пример использования "RestEasy" реализации JAX-RS 2.x для создания специального клиента "доверять всем" ...
связанные зависимости Maven
источник
Если вы используете Apache httpClient 4.5.x, попробуйте следующее:
источник