Si te encuentras con algún detalle que no entiendes puedes dejarlo en la sección de comentarios y haremos todo lo necesario de ayudarte rápidamente.
Solución:
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í el SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
a 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 el SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
bandera.
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 socketFactoryRegistry = RegistryBuilder
. create().register("https", sslsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
socketFactoryRegistry);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm).build();
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();
así como. (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
org.apache.httpcomponents
httpclient
4.5.3
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)
Al final de todo puedes encontrar las reseñas de otros programadores, tú igualmente tienes la libertad de insertar el tuyo si lo crees conveniente.