Ignoring SSL certificate in Apache HttpClient 4.3

How to ignore SSL certificate (trust all) for Apache HttpClient 4.3?

All the answers that I have found on SO treat previous versions, and the API changed.

Related:

  • How to ignore SSL certificate errors in Apache HttpClient 4.0
  • How to handle invalid SSL certificates with Apache HttpClient?
  • Need to trust all the certificates during the development using Spring
  • Ignore SSL Certificate Errors with Java

Edit:

  • It is only for test purposes. Kids, don't try it at home (or in production)

The code below works for trusting self-signed certificates. You have to use the TrustSelfSignedStrategy when creating your client:

SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
        sslsf).build();

HttpGet httpGet = new HttpGet("https://some-server");
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
} finally {
    response.close();
}

I did not include the SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER on purpose: The point was to allow testing with self signed certificates so you don't have to acquire a proper certificate from a certification authority. You can easily create a self-signed certificate with the correct host name, so do that instead of adding the SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER flag.

How to ignore SSL certificate errors in Apache HttpClient 4.0, You need to create a SSLContext with your own TrustManager and create HTTPS scheme using this context. Here is the code, SSLContext sslContext� How to ignore SSL certificate (trust all) for Apache HttpClient 4.3?. All the answers that I have found on SO treat previous versions, and the API changed. Related: How to ignore SSL certificate errors in Apache HttpClient 4.0

If you are using PoolingHttpClientConnectionManager procedure above doesn't work, custom SSLContext is ignored. You have to pass socketFactoryRegistry in contructor when creating PoolingHttpClientConnectionManager.

SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        return true;
    }
});
SSLContext sslContext = builder.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslContext, new X509HostnameVerifier() {
            @Override
            public void verify(String host, SSLSocket ssl)
                    throws IOException {
            }

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

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

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

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
        .<ConnectionSocketFactory> create().register("https", sslsf)
        .build();

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
        socketFactoryRegistry);
CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionManager(cm).build();

How to Ignore Certificate Errors in Apache HttpClient 4.5, In this example we demonstrates how to ignore SSL/TLS Certificate errors in Apache HttpClient 4.5. Self Signed Certificate Error. When you try to� Related: How to ignore SSL certificate errors in Apache HttpClient 4.0 How to handle invalid SSL certificates with Apache HttpClient? Need to trust all the certificates during the development using Spring Ignore SSL Certificate Errors with Java Edit: It is only for test purposes.

As an addition to the answer of @mavroprovato, if you want to trust all certificates instead of just self-signed, you'd do (in the style of your code)

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

or (direct copy-paste from my own code):

import javax.net.ssl.SSLContext;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContexts;

// ...

        SSLContext sslContext = SSLContexts
                .custom()
                //FIXME to contain real trust store
                .loadTrustMaterial(new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain,
                        String authType) throws CertificateException {
                        return true;
                    }
                })
                .build();

And if you want to skip hostname verification as well, you need to set

    CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
            sslsf).setSSLHostnameVerifier( NoopHostnameVerifier.INSTANCE).build();

as well. (ALLOW_ALL_HOSTNAME_VERIFIER is deprecated).

Obligatory warning: you shouldn't really do this, accepting all certificates is a bad thing. However there are some rare use cases where you want to do this.

As a note to code previously given, you'll want to close response even if httpclient.execute() throws an exception

CloseableHttpResponse response = null;
try {
    response = httpclient.execute(httpGet);
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
}
finally {
    if (response != null) {
        response.close();
    }
}

Code above was tested using

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

And for the interested, here's my full test set:

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.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class TrustAllCertificatesTest {
    final String expiredCertSite = "https://expired.badssl.com/";
    final String selfSignedCertSite = "https://self-signed.badssl.com/";
    final String wrongHostCertSite = "https://wrong.host.badssl.com/";

    static final TrustStrategy trustSelfSignedStrategy = new TrustSelfSignedStrategy();
    static final TrustStrategy trustAllStrategy = new TrustStrategy(){
        public boolean isTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            return true;
        }
    };

    @Test
    public void testSelfSignedOnSelfSignedUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLHandshakeException.class)
    public void testExpiredOnSelfSignedUsingCode() throws Exception {
        doGet(expiredCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnSelfSignedUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustSelfSignedStrategy);
    }

    @Test
    public void testSelfSignedOnTrustAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy);
    }
    @Test
    public void testExpiredOnTrustAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnTrustAllUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustAllStrategy);
    }

    @Test
    public void testSelfSignedOnAllowAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testExpiredOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testWrongHostOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }

    public void doGet(String url, TrustStrategy trustStrategy, HostnameVerifier hostnameVerifier) throws Exception {
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).setSSLHostnameVerifier(hostnameVerifier).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
    public void doGet(String url, TrustStrategy trustStrategy) throws Exception {

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
}

(working test project in github)

How to ignore SSL certificate errors in Apache HttpClient 4.4 , However, HttpClient's SSL configuration can be modified to allow this. Security aside, this technique is commonly done in earlier versions of� the certificate chain is invalid; the host name cannot be trusted; But the truth is: in this very context, I do not care. Disclaimer: of course such checks MUST be enabled against a production-like environment or external system. Using Apache HttpClient 4.x, disabling SSL checks is actually quite easy:

One small addition to the answer by vasekt:

The provided solution with the SocketFactoryRegistry works when using PoolingHttpClientConnectionManager.

However, connections via plain http don't work any longer then. You have to add a PlainConnectionSocketFactory for the http protocol additionally to make them work again:

Registry<ConnectionSocketFactory> socketFactoryRegistry = 
  RegistryBuilder.<ConnectionSocketFactory> create()
  .register("https", sslsf)
  .register("http", new PlainConnectionSocketFactory()).build();

java - Ignoring SSL certificate in Apache HttpClient 4.3, How to ignore SSL certificate (trust all) for Apache HttpClient 4.3? All the answers that I have found on SO treat previous versions, and the API changed. Related:. Ignorer le certificat SSL dans Apache HttpClient 4.3 comment ignorer un certificat SSL (trust all) pour Apache HttpClient 4.3 ? toutes les réponses que j'ai trouvées sur so treat versions précédentes, et L'API changé.

After trying various options, following configuration worked for both http and https

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);


        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", sslsf)
                .build();


        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        cm.setMaxTotal(2000);//max connection


        //System.setProperty("jsse.enableSNIExtension", "false"); //""
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setConnectionManager(cm)
                .build();

I am using http-client 4.3.3 -

compile 'org.apache.httpcomponents:httpclient:4.3.3'

disable SSL and host name verification for apache httpclient � GitHub, Disabling SSL checks with Apache HttpClient 4.3.x where the proxy in front of my application was an Nginx with a self signed certificate. However, HttpClient’s SSL configuration can be modified to allow this. Security aside, this technique is commonly done in earlier versions of HttpClient; but the configuration API (SSL configuration especially) API have changed radically in 4.4.

Disabling SSL checks with Apache HttpClient 4.3.x, HttpClient 4.3? SSLContextBuilder builder = new SSLContextBuilder(); builder. compile 'org.apache.httpcomponents:httpclient:4.3.3'. After trying various� Since you're using the HttpClient-based implementation, here are a couple of useful SO links on how to achieve this for the internal HttpClient: Ignoring SSL certificate in Apache HttpClient 4.3; How to ignore SSL certificate errors in Apache HttpClient 4.0; Apparently, since version 4.4, this can be done as:

java Ignoring SSL certificate in Apache HttpClient 4.3?, This article will show how to configure the Apache HttpClient 4 with “Accept All” The Spring RestTemplate with SSL (HttpClient < 4.3) An important thing to understand however is that this strategy entirely ignores certificate� How to ignore SSL certificate errors in Apache HttpClient 4.0. 101. Ignoring SSL certificate in Apache HttpClient 4.3. 10. Download file from HTTPS server using Java. 11.

HttpClient with SSL, How to ignore SSL certificate (trust all) for Apache HttpClient 4.3? All the answers that I have found on SO treat previous versions, and the API changed. Related:� Learn more about client-side SSL certificates and using the Apache HTTP Client 4.3 in this quick tutorial. Apache HTTP Client: Client-Side SSL Certificate - DZone Security Security Zone

Comments
  • I had to add the argument SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER to the constructor to get this working with the HttpClientBuilder (as mentioned in holmis83's response to vasekt).
  • also refer to the example on the httpclient site hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/…
  • I also had to use the ALLOW_ALL_HOSTNAME_VERIFIER: SSLConnectionSocketFactory(builder.build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  • This code works for me without using deprecated constructor with argument SSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
  • I wish you had specified full reference of the class you were using. Multiple classes called SSLContextBuilder are found by Idea.
  • Instead of building your own X509HostnameVerifier, you can use SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER.
  • As marked below by @rich95, the default for HttpClients is to give you a PoolingHttpClient, so this is relevant very often. I had to try quite a few of these answers before finding I needed this.
  • Tried to apply this on WebSphere and got "java.security.KeyStoreException: IBMTrustManager: Problem accessing trust store java.io.IOException: Invalid keystore format " To avoid you need pass KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); instead of null to builder.loadTrustMaterial
  • Actually, with HttpClient 4.5, both HttpClients.custom().setConnectionManager(cm).build() and HttpClients.custom().setSSLSocketFactory(connectionFactory).build() will work, so you don't need to create a PoolingHttpClientConnectionManager
  • How to use PoolingHttpClientConnectionManager after creating this , my code is working but i want to know does connection pooling works or not
  • HttpClient#execute will never return a null response object in case of an exception. Moreover, stock HttpClient implementations will ensure automatic deallocation of all system resources such as leased connections in case of an exception during request execution. Exception handling used by mavroprovato is perfectly adequate.