example defaulthttpclient java ssl https httpclient

java - defaulthttpclient - set sslcontext httpclient



HttpGet con HTTPS: SSLPeerUnverifiedException (5)

Esta excepción vendrá en caso de que su servidor esté basado en JDK 7 y su cliente esté en JDK 6 y use certificados SSL. En JDK 7, el apretón de manos del mensaje sslv2hello está deshabilitado de forma predeterminada mientras que en JDK 6 sslv2hello se habilita el protocolo de enlace. Por este motivo, cuando su cliente intenta conectarse al servidor, se enviará un mensaje sslv2hello al servidor y, debido a la desactivación del mensaje sslv2hello, obtendrá esta excepción. Para resolver esto, debe mover su cliente a JDK 7 o tiene que usar la versión 6u91 de JDK. Pero para obtener esta versión de JDK debes obtener el

Usando HttpClient , recibo el siguiente error cuando intento comunicarme a través de HTTPS:

Excepción en el hilo "main" javax.net.ssl.SSLPeerUnverifiedException: peer no autenticado.

Aquí está mi código:

URI loginUri = new URI("https://myUrl.asp"); HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet( loginUri ); HttpResponse response = httpclient.execute( httpget );

¿Cómo suprimo o elimino este error?


Esta respuesta sigue a owlstead y las respuestas de Mat . Se aplica a instalaciones SE / EE, no ME / mobile / Android SSL.

Como nadie lo ha mencionado aún, mencionaré la "forma de producción" para solucionarlo: siga los pasos de la clase AuthSSLProtocolSocketFactory en HttpClient para actualizar su tienda de confianza y almacenes de claves.

  1. Importe un certificado de confianza y genere un archivo de almacén de confianza

keytool -import -alias "my server cert" -file server.crt -keystore my.truststore

  1. Genera una nueva clave (usa la misma contraseña que el almacén de confianza)

keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore

  1. Emita una solicitud de firma de certificado (CSR)

keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore

  1. (auto-firmar o obtener su certificado firmado)

  2. Importe el certificado raíz de CA de confianza

keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore

  1. Importe el archivo PKCS # 7 que contiene la cadena de certificados completa

keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore

  1. Verificar los contenidos del archivo de keystore resultante

keytool -list -v -keystore my.keystore

Si no tiene un certificado de servidor, genere uno en formato JKS, luego expórtelo como un archivo CRT. Fuente: documentación de keytool

keytool -genkey -alias server-alias -keyalg RSA -keypass changeit -storepass changeit -keystore my.keystore keytool -export -alias server-alias -storepass changeit -file server.crt -keystore my.keystore


Método que devuelve un "cliente seguro" (en un entorno Java 7 - NetBeans IDE y GlassFish Server: puerto https por defecto 3920), espero que esto pueda ayudar:

public DefaultHttpClient secureClient() { DefaultHttpClient httpclient = new DefaultHttpClient(); SSLSocketFactory sf; KeyStore trustStore; FileInputStream trustStream = null; File truststoreFile; // java.security.cert.PKIXParameters for the trustStore PKIXParameters pkixParamsTrust; KeyStore keyStore; FileInputStream keyStream = null; File keystoreFile; // java.security.cert.PKIXParameters for the keyStore PKIXParameters pkixParamsKey; try { trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); truststoreFile = new File(TRUSTSTORE_FILE); keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keystoreFile = new File(KEYSTORE_FILE); try { trustStream = new FileInputStream(truststoreFile); keyStream = new FileInputStream(keystoreFile); } catch (FileNotFoundException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { trustStore.load(trustStream, PASSWORD.toCharArray()); keyStore.load(keyStream, PASSWORD.toCharArray()); } catch (IOException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } catch (CertificateException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { pkixParamsTrust = new PKIXParameters(trustStore); // accepts Server certificate generated with keytool and (auto) signed by SUN pkixParamsTrust.setPolicyQualifiersRejected(false); } catch (InvalidAlgorithmParameterException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { pkixParamsKey = new PKIXParameters(keyStore); // accepts Client certificate generated with keytool and (auto) signed by SUN pkixParamsKey.setPolicyQualifiersRejected(false); } catch (InvalidAlgorithmParameterException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { sf = new SSLSocketFactory(trustStore); ClientConnectionManager manager = httpclient.getConnectionManager(); manager.getSchemeRegistry().register(new Scheme("https", 3920, sf)); } catch (KeyManagementException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } catch (UnrecoverableKeyException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } } catch (NoSuchAlgorithmException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } catch (KeyStoreException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } // use the httpclient for any httpRequest return httpclient; }


Nota: No haga esto en el código de producción, use http en su lugar, o la clave pública autofirmada como se sugirió anteriormente.

En HttpClient 4.xx:

import static org.junit.Assert.assertEquals; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.junit.Test; public class HttpClientTrustingAllCertsTest { @Test public void shouldAcceptUnsafeCerts() throws Exception { DefaultHttpClient httpclient = httpClientTrustingAllSSLCerts(); HttpGet httpGet = new HttpGet("https://host_with_self_signed_cert"); HttpResponse response = httpclient.execute( httpGet ); assertEquals("HTTP/1.1 200 OK", response.getStatusLine().toString()); } private DefaultHttpClient httpClientTrustingAllSSLCerts() throws NoSuchAlgorithmException, KeyManagementException { DefaultHttpClient httpclient = new DefaultHttpClient(); SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, getTrustingManager(), new java.security.SecureRandom()); SSLSocketFactory socketFactory = new SSLSocketFactory(sc); Scheme sch = new Scheme("https", 443, socketFactory); httpclient.getConnectionManager().getSchemeRegistry().register(sch); return httpclient; } private TrustManager[] getTrustingManager() { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { // Do nothing } @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { // Do nothing } } }; return trustAllCerts; } }


Usando HttpClient 3.x, necesita hacer esto:

Protocol easyHttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443); Protocol.registerProtocol("https", easyHttps);

Una implementación de EasySSLProtocolSocketFactory se puede encontrar here .