Как игнорировать ошибки сертификата SSL в Apache HttpClient 4.0

Как обойти ошибки недействительных сертификатов SSL с помощью Apache HttpClient 4.0?


person Viet    schedule 24.04.2010    source источник
comment
Следует отметить, что ответы на этот вопрос не более того, чем задано: они позволяют игнорировать ошибку, но не устраняют основную проблему (что-то вроде извлечения батареек из дымовой пожарной сигнализации вместо тушения пожара. ). Сертификаты предназначены для обеспечения безопасности соединения SSL / TLS, игнорирование этих ошибок создает уязвимость для атаки MITM. Используйте тестовые сертификаты вместо игнорирования ошибки.   -  person Bruno    schedule 14.05.2012
comment
Связано с stackoverflow.com/questions/1828775/   -  person Gray    schedule 17.05.2012
comment
например, вынимая батарейки из детектора дыма. Вы можете дать другим разработчикам возможность сомневаться в своих силах и предположить, что они знают, что делают. Возможно, мотивом для этого вопроса является локальное тестирование, и OP желает провести быстрый тест, не проходя ужасное количество шаблонов Java, необходимых для настройки даже простой среды SSL. Может быть, кто-нибудь сможет просто ответить на этот вопрос, не вдаваясь в более святая лекция, чем ты.   -  person Mike    schedule 16.01.2014
comment
То есть на внутреннем сервере JIRA нашей компании есть сертификат на основе политики безопасности Windows, который действителен на машинах Windows, включенных в домен, и недействителен на других. Я не могу контролировать эту политику и все еще хочу вызвать JIRA REST API.   -  person odiszapc    schedule 05.04.2016
comment
@Bruno Невозможность отключить детекторы дыма на 30-60 минут при тушении небольшого кухонного пожара свидетельствует о безумном отсутствии понимания закономерностей использования некоторых официальных лиц в какой-то момент, что я считаю граничащим с преступлением. Об этом свидетельствует наличие концепции извлечения батареек из дымовой сигнализации. Я чувствую примерно такой же уровень гнева по поводу необходимости получать сертификаты для работы для простого теста, который, как я знаю, не имеет последствий для безопасности. Существование этого вопроса доказывает это.   -  person Bill K    schedule 21.03.2017
comment
@BillK Конечно, поймите меня правильно, я сам иногда отключал такую ​​проверку для простых тестов. Настоящая проблема в том, что большинство людей понимают, почему проблема с дымовой сигнализацией. В разработке программного обеспечения дело обстоит не так часто: эти строки кода не будут генерировать ошибок, и различным заинтересованным сторонам проекта (особенно тем, кто не приближается к коду) очень легко настаивать на выпуске продукта, не осознавая последствий. . Исправление вещей, которые не вызывают ошибок, обычно не является приоритетом, особенно когда у вас есть крайний срок.   -  person Bruno    schedule 21.03.2017
comment
@Bruno Похоже, я согласен - я хочу сказать, что не осознавать, что это проблема, - это недостаток дизайна. Если бы дизайнеры были более осведомлены об этой проблеме, они могли бы дать нам командную строку -Dignore_certs_unsafe = true, чтобы полностью отключить проверку сертификатов. Это довольно точное совпадение с аналогией с пожарной сигнализацией, где у них должна быть просто кнопка, чтобы отключить ее на 30 минут, вместо закона о том, что ее нельзя отключить. Иногда то, что считается большей безопасностью, на практике оказывается меньшей безопасностью :)   -  person Bill K    schedule 25.03.2017
comment
Хм, и на самом деле это может быть хорошим способом реализации этого взлома - установка переменной -D, которую вы включаете в среде запуска разработчика, но никогда не заставляете вас забыть об этом.   -  person Bill K    schedule 25.03.2017
comment
Если вы не хотите, чтобы это было безопасно, зачем вы вообще используете SSL?   -  person user207421    schedule 11.05.2017


Ответы (22)


Вам необходимо создать SSLContext с вашим собственным TrustManager и создать схему HTTPS, используя этот контекст. Вот код,

SSLContext sslContext = SSLContext.getInstance("SSL");

// set up a TrustManager that trusts everything
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                    System.out.println("getAcceptedIssuers =============");
                    return null;
            }

            public void checkClientTrusted(X509Certificate[] certs,
                            String authType) {
                    System.out.println("checkClientTrusted =============");
            }

            public void checkServerTrusted(X509Certificate[] certs,
                            String authType) {
                    System.out.println("checkServerTrusted =============");
            }
} }, new SecureRandom());

SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);

// apache HttpClient version >4.2 should use BasicClientConnectionManager
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm);
person ZZ Coder    schedule 24.04.2010
comment
Скажем, я не хочу покупать действующий сертификат SSL для своего сайта и просто хочу его использовать, этот фрагмент кода может помочь? Почему я не вижу части, в которой нужен URL-адрес или требуется обработка исключений? - person Viet; 24.04.2010
comment
Как видите, X509TrustManager ничего не проверяет и не генерирует никаких исключений, поэтому любой сертификат принимается. - person ZZ Coder; 24.04.2010
comment
Хм, он говорит мне, что «новый SSLSocketFactory (ssslCont)» ожидает хранилище ключей, а не SSLContext. Я что-то упускаю? - person MSpeed; 05.04.2012
comment
По какой-то причине причалы Jelatic и Heroku и серверы tomcat не могут уловить этот код, тогда как tomcat AWS beanstalk понимает и прекрасно его запускает ... странно. - person pulkitsinghal; 03.01.2013
comment
Я получаю сообщение об ошибке, что X509TrustManager не может быть преобразован в TrustManager. - person MW.; 16.01.2013
comment
Убедитесь, что вы импортируете правильные пакеты, т. Е. Из org.apache.http. - person warden; 21.06.2013
comment
Способ создания и настройки SSLContext пересмотрен в 4.3: SSLContext sslContext = SSLContexts.custom (). LoadTrustMaterial (null, new TrustSelfSignedStrategy ()). UseTLS (). Build (); - person Jay; 17.12.2013
comment
Кто-нибудь знает, как все это скинуть с помощью HttpClientBuilder? - person Ali; 13.02.2014
comment
Он работает для меня, а SSLContext, TrustManager и X509TrustManager - все из пакета javax.net.ssl - person alfonx; 03.06.2015
comment
какую версию HttpClient вы используете? - person ; 07.01.2016
comment
Этот метод совершенно и совершенно небезопасен. Не используйте. Импортируйте сертификат сервера в хранилище доверенных сертификатов клиента или получите сертификат сервера, подписанный центром сертификации. - person user207421; 11.05.2017

Все остальные ответы либо устарели, либо не работали для HttpClient 4.3.

Вот способ разрешить все имена хостов при создании http-клиента.

CloseableHttpClient httpClient = HttpClients
    .custom()
    .setHostnameVerifier(new AllowAllHostnameVerifier())
    .build();

Или, если вы используете версию 4.4 или новее, обновленный вызов выглядит так:

CloseableHttpClient httpClient = HttpClients
    .custom()
    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
    .build();
person erversteeg    schedule 23.06.2014
comment
Спасибо за ответ, я хотел бы знать, из какого пакета HttpsClients, поскольку я использую его в компиляции Android (org.apache.httpcomponents: httpclient: 4.3.4), но этот класс не отображается. - person Juan Saravia; 15.11.2014
comment
Это пакет org.apache.http.impl.client.HttpClients. - person erversteeg; 17.11.2014
comment
Это работает с несоответствием имени хоста (я предполагаю), но, похоже, это не работает, если сертификат не подписан доверенным центром. - person twm; 25.01.2017
comment
@twm, поэтому он говорит, что разрешает все имена хостов, проблемы с доверием требуют другой конфигурации. - person eis; 30.08.2017
comment
@eis, я указывал, что в некоторых случаях этот ответ касается исходного вопроса, но не других. - person twm; 30.08.2017
comment
не работает на 4.5.9 - person user124; 07.07.2021

Просто пришлось сделать это с новым HttpClient 4.5, и похоже, что они устарели с версии 4.4, поэтому вот фрагмент, который работает для меня и использует самый последний API:

final SSLContext sslContext = new SSLContextBuilder()
        .loadTrustMaterial(null, (x509CertChain, authType) -> true)
        .build();

return HttpClientBuilder.create()
        .setSSLContext(sslContext)
        .setConnectionManager(
                new PoolingHttpClientConnectionManager(
                        RegistryBuilder.<ConnectionSocketFactory>create()
                                .register("http", PlainConnectionSocketFactory.INSTANCE)
                                .register("https", new SSLConnectionSocketFactory(sslContext,
                                        NoopHostnameVerifier.INSTANCE))
                                .build()
                ))
        .build();
person Z4-    schedule 21.07.2016
comment
Работал у меня также для httpclient 4.5.2 - person Vikas Ranjan; 23.01.2018
comment
это актуально для HttpClient 4.5 - person You're awesome; 07.10.2018

Apache HttpClient 4.5.5

HttpClient httpClient = HttpClients
            .custom()
            .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();

Устаревший API не использовался.

Простой проверяемый тестовый пример:

package org.apache.http.client.test;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

public class ApacheHttpClientTest {

    private HttpClient httpClient;

    @Before
    public void initClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
        httpClient = HttpClients
                .custom()
                .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
    }

    @Test
    public void apacheHttpClient455Test() throws IOException {
        executeRequestAndVerifyStatusIsOk("https://expired.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://wrong.host.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://self-signed.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://untrusted-root.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://revoked.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://pinning-test.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://sha1-intermediate.badssl.com");
    }

    private void executeRequestAndVerifyStatusIsOk(String url) throws IOException {
        HttpUriRequest request = new HttpGet(url);

        HttpResponse response = httpClient.execute(request);
        int statusCode = response.getStatusLine().getStatusCode();

        assert statusCode == 200;
    }
}
person Mikhail Kholodkov    schedule 10.05.2018
comment
Спасибо! Просто замените TrustAllStrategy.INSTANCE на TrustSelfSignedStrategy.INSTANCE в этом ответе. - person Percy Vega; 16.09.2019
comment
У меня это не сработало. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: сбой построения пути PKIX: sun.security. provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации для запрошенной цели - person ggb667; 22.06.2020
comment
@ ggb667 Я не нашел TrustAllStrategy.INSTANCE, но пытаюсь реализовать это самостоятельно: new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build(), и это сработало. - person Svichkarev Anatoly; 18.11.2020
comment
.setSSLContext () в зависимости Apache 4.5.6 на самом деле вызывает ошибку? Изменив его на .setSslContext (), ошибка исчезла ?? Если они не изменили его в 4.5.6, это должен быть .setSslContext () с Ssl в нижнем регистре. - person whyoz; 26.05.2021

Просто для записи, есть гораздо более простой способ сделать то же самое с HttpClient 4.1.

    SSLSocketFactory sslsf = new SSLSocketFactory(new TrustStrategy() {

        public boolean isTrusted(
                final X509Certificate[] chain, String authType) throws CertificateException {
            // Oh, I am easy...
            return true;
        }

    });
person ok2c    schedule 01.05.2012
comment
Вам не хватает кода в этом примере? Может, вызов httpClient.set ...? - person Gray; 17.05.2012
comment
httpclient.getConnectionManager (). getSchemeRegistry (). register (новая схема (https, 443, sslsf)); - person Ben Flynn; 06.04.2013
comment
SSLSocketFactory устарел в HttpClient 4.3 - person Toilal; 08.01.2014
comment
Если вы используете Java 8, вы можете даже new SSLSocketFactory((chain, authType) -> true); - person jlb; 27.04.2015

Для записи, протестировано с httpclient 4.3.6 и совместимо с Executor fluent api:

CloseableHttpClient httpClient = HttpClients.custom().
                    setHostnameVerifier(new AllowAllHostnameVerifier()).
                    setSslcontext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy()
                    {
                        public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
                        {
                            return true;
                        }
                    }).build()).build();
person STM    schedule 18.12.2014
comment
Для HttpClient 4.4 и выше вы должны это сделать - и, возможно, также потребуется создать SSLConnectionSocketFactory, используя этот SSLContext, и определить это в Registry<ConnectionSocketFactory>, если вы собираетесь создать PoolingHttpClientConnectionManager. Другие ответы более популярны, но не работают в HttpClient 4.4. - person Thomas W; 04.03.2015
comment
Точно так же работает с httpclient-4.3.5.jar. - person Harald; 28.01.2016

Для Apache HttpClient 4.4:

HttpClientBuilder b = HttpClientBuilder.create();

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
    public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        return true;
    }
}).build();
b.setSslcontext( sslContext);

// or SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.getSocketFactory())
        .register("https", sslSocketFactory)
        .build();

// allows multi-threaded use
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
b.setConnectionManager( connMgr);

HttpClient client = b.build();

Это извлечено из нашей реальной рабочей реализации.

Другие ответы популярны, но для HttpClient 4.4 они не работают. Я потратил часы на попытки и исчерпание возможностей, но, похоже, произошли чрезвычайно серьезные изменения и перемещение API в 4.4.

См. Также более подробное объяснение по адресу: http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/

Надеюсь, это поможет!

person Thomas W    schedule 04.03.2015

Если все, что вы хотите сделать, это избавиться от ошибок неверного имени хоста, вы можете просто сделать:

HttpClient httpClient = new DefaultHttpClient();
SSLSocketFactory sf = (SSLSocketFactory)httpClient.getConnectionManager()
    .getSchemeRegistry().getScheme("https").getSocketFactory();
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
person David Tinker    schedule 12.05.2011
comment
Метод sf.setHostnameVerifier устарел с версии 4.1. Альтернатива - использовать один из конструкторов. Например: SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - person kaliatech; 02.06.2011

Мы используем HTTPClient 4.3.5, и мы попробовали почти все решения, существующие в stackoverflow, но ничего. Подумав и выяснив проблему, мы приходим к следующему коду, который отлично работает, просто добавьте его перед созданием экземпляра HttpClient.

какой-то метод для вызова при отправке почтовых запросов ....

SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(null, new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return true;
        }
    });

    SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(builder.build(),
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSF).build();
    HttpPost postRequest = new HttpPost(url);

продолжить свой запрос в обычной форме

person Hamed MP    schedule 03.04.2015

В fluent 4.5.2 мне пришлось внести следующую модификацию, чтобы она работала.

try {
    TrustManager[] trustAllCerts = new TrustManager[] {
       new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }
    public void checkClientTrusted(X509Certificate[] certs, String authType) {  }

    public void checkServerTrusted(X509Certificate[] certs, String authType) {  }
    }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSslcontext(sc).build();

    String output = Executor.newInstance(httpClient).execute(Request.Get("https://127.0.0.1:3000/something")
                                      .connectTimeout(1000)
                                      .socketTimeout(1000)).returnContent().asString();
    } catch (Exception e) {
    }
person Talespin_Kit    schedule 18.09.2016
comment
Это единственное решение, которое у меня сработало. Я пробовал вышеуказанные решения для 4.3 и 4.4 перед обновлением до 4.5 и пробовал это. - person dirkoneill; 29.10.2016

Вот как я это сделал -

  1. Создайте свой собственный MockSSLSocketFactory (класс прилагается ниже)
  2. Используйте его для инициализации DefaultHttpClient. Если используется прокси, необходимо указать настройки прокси.

Инициализация DefaultHTTPClient -

SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
    schemeRegistry.register(new Scheme("https", 443, new MockSSLSocketFactory()));
    ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);

    DefaultHttpClient httpclient = new DefaultHttpClient(cm);

Фабрика имитаций SSL -

public class MockSSLSocketFactory extends SSLSocketFactory {

public MockSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
    super(trustStrategy, hostnameVerifier);
}

private static final X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
    @Override
    public void verify(String host, SSLSocket ssl) throws IOException {
        // Do nothing
    }

    @Override
    public void verify(String host, X509Certificate cert) throws SSLException {
        //Do nothing
    }

    @Override
    public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
        //Do nothing
    }

    @Override
    public boolean verify(String s, SSLSession sslSession) {
        return true; 
    }
};

private static final TrustStrategy trustStrategy = new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return true;
    }
};
}

Если за прокси, нужно сделать это -

HttpParams params = new BasicHttpParams();
    params.setParameter(AuthPNames.PROXY_AUTH_PREF, getClientAuthPrefs());

DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);

httpclient.getCredentialsProvider().setCredentials(
                        new AuthScope(proxyHost, proxyPort),
                        new UsernamePasswordCredentials(proxyUser, proxyPass));
person Swaroop Rath    schedule 16.08.2012
comment
Было бы полезно, если бы вы включили импорт в будущем. Есть два разных класса. - person AndroidDev; 06.12.2012

Протестировано с HttpClient 4.5.5 с Fluent API

final SSLContext sslContext = new SSLContextBuilder()
    .loadTrustMaterial(null, (x509CertChain, authType) -> true).build();

CloseableHttpClient httpClient = HttpClients.custom()
    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
    .setSSLContext(sslContext).build();

String result = Executor.newInstance(httpClient)
    .execute(Request.Get("https://localhost:8080/someapi")
    .connectTimeout(1000).socketTimeout(1000))
    .returnContent().asString();
person Lachesis    schedule 05.04.2018

В дополнение к ответ ZZ Coder было бы неплохо переопределить hostnameverifier.

// ...
SSLSocketFactory sf = new SSLSocketFactory (sslContext);
sf.setHostnameVerifier(new X509HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }

    public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
    }

    public void verify(String host, X509Certificate cert) throws SSLException {
    }

    public void verify(String host, SSLSocket ssl) throws IOException {
    }
});
// ...
person eldur    schedule 08.10.2010
comment
Вы можете добиться того же, просто выполнив sf.setHostnameVerifier(new AllowAllHostnameVerifier()); - person Dan Dyer; 05.05.2011
comment
Sf.setHostnameVerifier устарел с версии 4.1. Альтернативный вариант - использовать один из конструкторов. Например: SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - person kaliatech; 02.06.2011

Чтобы принять все сертификаты в HttpClient 4.4.x, вы можете использовать следующий лайнер при создании httpClient:

httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()).setSslcontext(new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true).build()).build();
person Chilly    schedule 15.04.2015
comment
Я получаю следующее: вызвано: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: нет альтернативных имен субъектов? - person ; 07.01.2016
comment
Как разрешить подключения к SSL-сайтам без сертификатов в HttpClient API или RestClient API? - person ; 07.01.2016

Код ниже работает с 4.5.5

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

class HttpsSSLClient {


    public static CloseableHttpClient createSSLInsecureClient() {
        SSLContext sslcontext = createSSLContext();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new HostnameVerifier() {

            @Override
            public boolean verify(String paramString, SSLSession paramSSLSession) {
                return true;
            }
        });
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        return httpclient;
    }


    private static SSLContext createSSLContext() {
        SSLContext sslcontext = null;
        try {
            sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(null, new TrustManager[] {new TrustAnyTrustManager()}, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslcontext;
    }


    private static class TrustAnyTrustManager implements X509TrustManager {

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }

}
public class TestMe {


    public static void main(String[] args) throws IOException {
        CloseableHttpClient client = HttpsSSLClient.createSSLInsecureClient();

        CloseableHttpResponse res = client.execute(new HttpGet("https://wrong.host.badssl.com/"));
        System.out.println(EntityUtils.toString(res.getEntity()));
    }
}

Вывод из кода

Код

Вывод в браузере

Плохой SSL

Используемый помпон ниже

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tarun</groupId>
    <artifactId>testing</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>6</source>
                    <target>6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.5</version>
    </dependency>

</dependencies>
</project>
person Tarun Lalwani    schedule 08.05.2018

Проверено на 4.5.4:

            SSLContext sslContext = new SSLContextBuilder()
                    .loadTrustMaterial(null, (TrustStrategy) (arg0, arg1) -> true).build();

            CloseableHttpClient httpClient = HttpClients
                    .custom()
                    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                    .setSSLContext(sslContext)
                    .build();
person Jacky    schedule 14.12.2017

полная рабочая версия для Apache HttpClient 4.1.3 (на основе приведенного выше кода Олега, но в моей системе по-прежнему нужен allow_all_hostname_verifier):

private static HttpClient trustEveryoneSslHttpClient() {
    try {
        SchemeRegistry registry = new SchemeRegistry();

        SSLSocketFactory socketFactory = new SSLSocketFactory(new TrustStrategy() {

            public boolean isTrusted(final X509Certificate[] chain, String authType) throws CertificateException {
                // Oh, I am easy...
                return true;
            }

        }, org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        registry.register(new Scheme("https", 443, socketFactory));
        ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry);
        DefaultHttpClient client = new DefaultHttpClient(mgr, new DefaultHttpClient().getParams());
        return client;
    } catch (GeneralSecurityException e) {
        throw new RuntimeException(e);
    }
}

Заметьте, я повторно выбрасываю все исключения, потому что на самом деле я мало что могу сделать, если что-то из этого выйдет из строя в реальной системе!

person Korny    schedule 31.05.2012

Если вы используете fluent API, вам необходимо настроить его через Executor:

Executor.unregisterScheme("https");
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(sslContext,
                                  SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Executor.registerScheme(new Scheme("https", 443, sslSocketFactory));

... где sslContext - это SSLContext, созданный, как показано в ответе ZZ Coder.

После этого вы можете выполнять свои http-запросы как:

String responseAsString = Request.Get("https://192.168.1.0/whatever.json")
                         .execute().getContent().asString();

Примечание: протестировано с HttpClient 4.2

person Elias Dorneles    schedule 04.07.2013
comment
К сожалению, не рекомендуется в 4.3: Устарело. (4.3) не используйте. - person STM; 06.08.2014

Протестировано с 4.3.3

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class AccessProtectedResource {

public static void main(String[] args) throws Exception {

    // Trust all certs
    SSLContext sslcontext = buildSSLContext();

    // Allow TLSv1 protocol only
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
            sslcontext,
            new String[] { "TLSv1" },
            null,
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLSocketFactory(sslsf)
            .build();
    try {

        HttpGet httpget = new HttpGet("https://yoururl");

        System.out.println("executing request" + httpget.getRequestLine());

        CloseableHttpResponse response = httpclient.execute(httpget);
        try {
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            if (entity != null) {
                System.out.println("Response content length: " + entity.getContentLength());
            }
            for (Header header : response.getAllHeaders()) {
                System.out.println(header);
            }
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    } finally {
        httpclient.close();
    }
}

private static SSLContext buildSSLContext()
        throws NoSuchAlgorithmException, KeyManagementException,
        KeyStoreException {
    SSLContext sslcontext = SSLContexts.custom()
            .setSecureRandom(new SecureRandom())
            .loadTrustMaterial(null, new TrustStrategy() {

                public boolean isTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {
                    return true;
                }
            })
            .build();
    return sslcontext;
}

}

person craftsmannadeem    schedule 08.07.2014
comment
Как установить значения в заголовках, если я хотел это сделать? - person ; 07.01.2016

Если вы столкнулись с этой проблемой при использовании AmazonS3Client, который включает Apache HttpClient 4.1, вам просто нужно определить такое системное свойство, чтобы упростить проверку сертификата SSL:

-Dcom.amazonaws.sdk.disableCertChecking = true

Шалость удалась

person Mike Slinn    schedule 24.09.2012

fwiw, пример использования "RestEasy" реализации JAX-RS 2.x для создания специального клиента "доверять всем" ...

    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.security.GeneralSecurityException;
    import java.security.KeyManagementException;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.Arrays;
    import javax.ejb.Stateless;
    import javax.net.ssl.SSLContext;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import javax.ws.rs.client.Entity;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.HttpClientConnectionManager;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.jboss.resteasy.client.jaxrs.ResteasyClient;
    import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
    import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
    import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
    import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.ssl.SSLContexts;

    @Stateless
    @Path("/postservice")
    public class PostService {

        private static final Logger LOG = LogManager.getLogger("PostService");

        public PostService() {
        }

        @GET
        @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
        public PostRespDTO get() throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException, IOException, GeneralSecurityException {

            //...object passed to the POST method...
            PostDTO requestObject = new PostDTO();
            requestObject.setEntryAList(new ArrayList<>(Arrays.asList("ITEM0000A", "ITEM0000B", "ITEM0000C")));
            requestObject.setEntryBList(new ArrayList<>(Arrays.asList("AAA", "BBB", "CCC")));

            //...build special "trust all" client to call POST method...
            ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(createTrustAllClient());

            ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
            ResteasyWebTarget target = client.target("https://localhost:7002/postRespWS").path("postrespservice");
            Response response = target.request().accept(MediaType.APPLICATION_JSON).post(Entity.entity(requestObject, MediaType.APPLICATION_JSON));

            //...object returned from the POST method...
            PostRespDTO responseObject = response.readEntity(PostRespDTO.class);

            response.close();

            return responseObject;
        }


        //...get special "trust all" client...
        private static CloseableHttpClient createTrustAllClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {

            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, TRUSTALLCERTS).useProtocol("TLS").build();
            HttpClientBuilder builder = HttpClientBuilder.create();
            NoopHostnameVerifier noop = new NoopHostnameVerifier();
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, noop);
            builder.setSSLSocketFactory(sslConnectionSocketFactory);
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("https", sslConnectionSocketFactory).build();
            HttpClientConnectionManager ccm = new BasicHttpClientConnectionManager(registry);
            builder.setConnectionManager(ccm);

            return builder.build();
        }


        private static final TrustStrategy TRUSTALLCERTS = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
                return true;
            }
        };
    }

связанные зависимости Maven

    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>3.0.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>jaxrs-api</artifactId>
        <version>3.0.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jackson2-provider</artifactId>
        <version>3.0.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency> 
person sairn    schedule 04.02.2016

Если вы используете Apache httpClient 4.5.x, попробуйте следующее:

public static void main(String... args)  {

    try (CloseableHttpClient httpclient = createAcceptSelfSignedCertificateClient()) {
        HttpGet httpget = new HttpGet("https://example.com");
        System.out.println("Executing request " + httpget.getRequestLine());

        httpclient.execute(httpget);
        System.out.println("----------------------------------------");
    } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException | IOException e) {
        throw new RuntimeException(e);
    }
}

private static CloseableHttpClient createAcceptSelfSignedCertificateClient()
        throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {

    // use the TrustSelfSignedStrategy to allow Self Signed Certificates
    SSLContext sslContext = SSLContextBuilder
            .create()
            .loadTrustMaterial(new TrustSelfSignedStrategy())
            .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 = new NoopHostnameVerifier();

    // create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy
    // and allow all hosts verifier.
    SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);

    // finally create the HttpClient using HttpClient factory methods and assign the ssl socket factory
    return HttpClients
            .custom()
            .setSSLSocketFactory(connectionFactory)
            .build();
}
person Brijesh Patel    schedule 04.05.2018