Ignorando el certificado SSL en Apache HttpClient 4.3

102

¿Cómo ignorar el certificado SSL (confiar en todos) para Apache HttpClient 4.3 ?

Todas las respuestas que he encontrado en SO tratan versiones anteriores y la API cambió.

Relacionado:

Editar:

  • Es solo para fines de prueba. Niños, no lo prueben en casa (o en producción)
Jakub M.
fuente

Respuestas:

146

El siguiente código funciona para confiar en certificados autofirmados. Debe utilizar TrustSelfSignedStrategy al crear su cliente:

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();
}

No incluí SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERel propósito: el objetivo era permitir las pruebas con certificados autofirmados para que no tenga que adquirir un certificado adecuado de una autoridad de certificación. Puede crear fácilmente un certificado autofirmado con el nombre de host correcto, así que hágalo en lugar de agregar la SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERmarca.

mavroprovato
fuente
8
Tuve que agregar el argumento SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER al constructor para que esto funcione con HttpClientBuilder (como se menciona en la respuesta de holmis83 a vasekt).
dejuknow
también consulte el ejemplo en el sitio httpclient hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/…
arajashe
2
También tuve que usar ALLOW_ALL_HOSTNAME_VERIFIER: SSLConnectionSocketFactory (builder.build (), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Nombre
Este código funciona para mí sin usar un constructor obsoleto con argumentoSSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
user11153
Ojalá hubieras especificado una referencia completa de la clase que estabas usando. SSLContextBuilderIdea encuentra varias clases llamadas .
MasterMind
91

Si está utilizando el procedimiento PoolingHttpClientConnectionManager anterior no funciona, se ignora el SSLContext personalizado. Debe pasar socketFactoryRegistry en contructor al crear 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();
vasekt
fuente
11
En lugar de crear su propio X509HostnameVerifier, puede usar SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER.
holmis83
Como se indica a continuación con @ rich95, el valor predeterminado para HttpClients es darle un PoolingHttpClient, por lo que esto es relevante muy a menudo. Tuve que probar algunas de estas respuestas antes de descubrir que necesitaba esto.
SunSear
1
Intenté aplicar esto en WebSphere y obtuve "java.security.KeyStoreException: IBMTrustManager: Problema al acceder al almacén de confianza java.io.IOException: Formato de almacén de claves no válido" Para evitarlo, debe pasar KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType ()); en lugar de nulo a builder.loadTrustMaterial
Georgy Gobozov
1
En realidad, con HttpClient 4.5, ambos HttpClients.custom().setConnectionManager(cm).build()y HttpClients.custom().setSSLSocketFactory(connectionFactory).build()funcionarán, por lo que no es necesario crear unaPoolingHttpClientConnectionManager
soulmachine
Cómo usar PoolingHttpClientConnectionManager después de crear esto, mi código está funcionando pero quiero saber si la agrupación de conexiones funciona o no
Labeo
34

Como una adición a la respuesta de @mavroprovato, si desea confiar en todos los certificados en lugar de solo autofirmados, lo haría (en el estilo de su código)

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

o (copiar y pegar directamente desde mi propio código):

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();

Y si también desea omitir la verificación del nombre de host, debe configurar

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

también. (ALLOW_ALL_HOSTNAME_VERIFIER está obsoleto).

Advertencia obligatoria: realmente no debería hacer esto, aceptar todos los certificados es algo malo. Sin embargo, hay algunos casos de uso poco comunes en los que desea hacer esto.

Como nota al código dado anteriormente, querrá cerrar la respuesta incluso si httpclient.execute () arroja una excepción

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();
    }
}

El código anterior se probó usando

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

Y para los interesados, aquí está mi conjunto de prueba completo:

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();
        }
    }
}

(proyecto de prueba de trabajo en github )

eis
fuente
1
HttpClient # execute nunca devolverá un objeto de respuesta nulo en caso de una excepción. Además, las implementaciones estándar de HttpClient garantizarán la desasignación automática de todos los recursos del sistema, como las conexiones alquiladas, en caso de una excepción durante la ejecución de la solicitud. El manejo de excepciones utilizado por mavroprovato es perfectamente adecuado.
ok2c
@oleg, el objetivo de la interfaz que se puede cerrar es "Cerrar la [...] transmisión y liberar los recursos del sistema asociados a ella. Si la transmisión ya está cerrada, la invocación de este método no tiene ningún efecto". por lo que es una buena práctica usarlo incluso si no fuera necesario. Además, no entiendo el comentario de devolver una respuesta nula; por supuesto que no, si lanza una excepción, ¿no devuelve nada?
EIS
1
Apache HttpClient no siempre devuelve un valor nulo o parcialmente inicializado objeto respuesta. Esto no tiene nada que ver con la cantidad de veces que se invoca #close, sino una verificación nula completamente innecesaria en la cláusula
final
@oleg y nunca el código que he dado asume que devolvería un objeto de respuesta nulo o parcialmente inicializado, o incluso verificaría tal caso. ¿No tengo ni idea de lo que estás hablando?
EIS
1
[ suspiro ] que es completamente innecesario dado que HttpResponse nunca puede ser nulo y en caso de una excepción, el método #execute terminará sin devolver una respuesta ;-)
ok2c
22

Una pequeña adición a la respuesta de vasekt:

La solución proporcionada con SocketFactoryRegistry funciona cuando se usa PoolingHttpClientConnectionManager.

Sin embargo, las conexiones a través de http simple ya no funcionan. Debe agregar un PlainConnectionSocketFactory para el protocolo http adicionalmente para que funcionen nuevamente:

Registry<ConnectionSocketFactory> socketFactoryRegistry = 
  RegistryBuilder.<ConnectionSocketFactory> create()
  .register("https", sslsf)
  .register("http", new PlainConnectionSocketFactory()).build();
migo
fuente
Creo que el httpprotocolo se usa PlainConnectionSocketFactory de forma predeterminada. Solo me registré httpsy httpclienttodavía puedo obtener URL HTTP simples. por lo que no creo que este paso sea necesario.
soulmachine
@soulmachine no será porPoolingHttpClientConnectionManager
amseager
15

Después de probar varias opciones, la siguiente configuración funcionó tanto para http como para 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();

Estoy usando http-client 4.3.3 -

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

Saurabh
fuente
1
¡Gracias por proporcionar un ejemplo completo y completamente funcional! Tenía varios problemas con las soluciones anteriores y esto ayudó enormemente. También ayudó que haya proporcionado las declaraciones de importación, ya que hay varias clases con los mismos nombres, lo que aumenta la confusión.
helmy
8

Código de trabajo más simple y corto:

Estamos usando HTTPClient 4.3.5 y probamos casi todas las soluciones que existen en el stackoverflow pero nada. Después de pensar y resolver el problema, llegamos al siguiente código que funciona perfectamente, simplemente agréguelo antes de crear la instancia de HttpClient.

algún método que utilizas para hacer una solicitud de publicación ...

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);

continuar llamando y usando la instancia de HttpPost en la forma normal

MP de Hamed
fuente
¿Cómo podemos publicar datos en encabezados? Si lo hicimos, ver HTTP / 1.1 400 Bad Request
6

Aquí hay una destilación de trabajo de las técnicas anteriores, equivalente a "curl --insecure":

HttpClient getInsecureHttpClient() throws GeneralSecurityException {
    TrustStrategy trustStrategy = new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) {
            return true;
        }
    };

    HostnameVerifier hostnameVerifier = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    return HttpClients.custom()
            .setSSLSocketFactory(new SSLConnectionSocketFactory(
                    new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(),
                    hostnameVerifier))
            .build();
}
divbyzero
fuente
5

Cuando usé el cliente http 4.5, tuve que usar javasx.net.ssl.HostnameVerifier para permitir cualquier nombre de host (con fines de prueba). Esto es lo que terminé haciendo:

CloseableHttpClient httpClient = null;
    try {
        SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
        sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());

        HostnameVerifier hostnameVerifierAllowAll = new HostnameVerifier() 
            {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
            new AuthScope("192.168.30.34", 8443),
            new UsernamePasswordCredentials("root", "password"));

        httpClient = HttpClients.custom()
            .setSSLSocketFactory(sslSocketFactory)
            .setDefaultCredentialsProvider(credsProvider)
            .build();

        HttpGet httpGet = new HttpGet("https://192.168.30.34:8443/axis/services/getStuff?firstResult=0&maxResults=1000");

        CloseableHttpResponse response = httpClient.execute(httpGet);

        int httpStatus = response.getStatusLine().getStatusCode();
        if (httpStatus >= 200 && httpStatus < 300) { [...]
        } else {
            throw new ClientProtocolException("Unexpected response status: " + httpStatus);
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    finally {
        try {
            httpClient.close();
        } catch (IOException ex) {
            logger.error("Error while closing the HTTP client: ", ex);
        }
    }
Kurt
fuente
La implementación de HostnameVerifier resolvió el problema de HTTPClient 4.5.
digz6666
para aquellos que aman las lambdas (JDK1.8), pueden reemplazar SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);con SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. Evita la clase anónima y hace que el código sea un poco más legible.
Vielinko
3

Además de PoolingHttpClientConnectionManagerjunto con Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); Si desea un cliente http asincrónico que use PoolingNHttpClientConnectionManagerel código, debe ser similar a lo siguiente

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();
SchemeIOSessionStrategy sslioSessionStrategy = new SSLIOSessionStrategy(sslContext, 
                new HostnameVerifier(){
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;// TODO as of now allow all hostnames
            }
        });
Registry<SchemeIOSessionStrategy> sslioSessionRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create().register("https", sslioSessionStrategy).build();
PoolingNHttpClientConnectionManager ncm  = new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor(),sslioSessionRegistry);
CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.custom().setConnectionManager(ncm).build();
asyncHttpClient.start();        
Anant Laxmikant Bobde
fuente
3

Si está utilizando HttpClient 4.5.x, su código puede ser similar al siguiente:

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
        TrustSelfSignedStrategy.INSTANCE).build();
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
        sslContext, NoopHostnameVerifier.INSTANCE);

HttpClient httpClient = HttpClients.custom()
                                   .setDefaultCookieStore(new BasicCookieStore())
                                   .setSSLSocketFactory(sslSocketFactory)
                                   .build();
Pablo Vargas
fuente
No funcionó para mí. Estoy usando HttpClient: 4.5.5. y HttpCore 4.4.9
Vijay Kumar
2
class ApacheHttpClient {

    /***
     * This is a https get request that bypasses certificate checking and hostname verifier.
     * It uses basis authentication method.
     * It is tested with Apache httpclient-4.4.
     * It dumps the contents of a https page on the console output.
     * It is very similar to http get request, but with the additional customization of
     *   - credential provider, and
     *   - SSLConnectionSocketFactory to bypass certification checking and hostname verifier.
     * @param path String
     * @param username String
     * @param password String
     * @throws IOException
     */
    public void get(String path, String username, String password) throws IOException {
        final CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCredentialsProvider(createCredsProvider(username, password))
                .setSSLSocketFactory(createGenerousSSLSocketFactory())
                .build();

        final CloseableHttpResponse response = httpClient.execute(new HttpGet(path));
        try {
            HttpEntity entity = response.getEntity();
            if (entity == null)
                return;
            System.out.println(EntityUtils.toString(entity));
        } finally {
            response.close();
            httpClient.close();
        }
    }

    private CredentialsProvider createCredsProvider(String username, String password) {
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        return credsProvider;
    }

    /***
     * 
     * @return SSLConnectionSocketFactory that bypass certificate check and bypass HostnameVerifier
     */
    private SSLConnectionSocketFactory createGenerousSSLSocketFactory() {
        SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{createGenerousTrustManager()}, new SecureRandom());
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
        return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    }

    private X509TrustManager createGenerousTrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
    }
}
Dahai Li
fuente
2

Confíe en todos los certificados en el cliente HTTP Apache

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

          try {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sc);
                httpclient = HttpClients.custom().setSSLSocketFactory(
                        sslsf).build();
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Jeff Z
fuente
Esto funcionó bien con httpclient 4.5.9, simplemente copie y pegue todo el contenido, eso es todo.
sathya
1

(Habría agregado un comentario directamente a la respuesta de vasekt pero no tengo suficientes puntos de reputación (no estoy seguro de la lógica)

De todos modos ... lo que quería decir es que incluso si no está creando / solicitando explícitamente una PoolingConnection, no significa que no esté obteniendo una.

Me estaba volviendo loco tratando de averiguar por qué la solución original no funcionó para mí, pero ignoré la respuesta de vasekt ya que "no se aplicaba a mi caso", ¡mal!

Estaba mirando mi rastro de pila cuando estaba bajo y he aquí que vi una PoolingConnection en el medio. Bang - ¡¡Me cansé de su adición y éxito !! (nuestra demostración es mañana y me estaba desesperando) :-)

rich95
fuente
0

Puede usar el siguiente fragmento de código para obtener la instancia de HttpClient sin la verificación de la certificación ssl.

private HttpClient getSSLHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        LogLoader.serverLog.trace("In getSSLHttpClient()");

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

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

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

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

        context.init(null, new TrustManager[] { tm }, null);

        HttpClientBuilder builder = HttpClientBuilder.create();
        SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(context);
        builder.setSSLSocketFactory(sslConnectionFactory);

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

        PoolingHttpClientConnectionManager ccm = new PoolingHttpClientConnectionManager(registry);
        ccm.setMaxTotal(BaseConstant.CONNECTION_POOL_SIZE);
        ccm.setDefaultMaxPerRoute(BaseConstant.CONNECTION_POOL_SIZE);
        builder.setConnectionManager((HttpClientConnectionManager) ccm);

        builder.disableRedirectHandling();

        LogLoader.serverLog.trace("Out getSSLHttpClient()");

        return builder.build();
    }
Radadiya Nikunj
fuente
0

Ligero ajuste para responder desde @divbyzero arriba para corregir las advertencias de seguridad de la sonda

CloseableHttpClient getInsecureHttpClient() throws GeneralSecurityException {
            TrustStrategy trustStrategy = (chain, authType) -> true;

            HostnameVerifier hostnameVerifier = (hostname, session) -> hostname.equalsIgnoreCase(session.getPeerHost());

            return HttpClients.custom()
                    .setSSLSocketFactory(new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(), hostnameVerifier))
                    .build();
        }
andyd
fuente
0

Inicialmente, pude deshabilitar localhost usando una estrategia de confianza, luego agregué NoopHostnameVerifier. Ahora funcionará tanto para localhost como para cualquier nombre de máquina

SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(null, new TrustStrategy() {

            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }

        }).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext, NoopHostnameVerifier.INSTANCE);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
U_R_Naveen UR_Naveen
fuente