2012-03-06 26 views
28
public HttpClientVM() { 

    BasicHttpParams params = new BasicHttpParams(); 
    ConnManagerParams.setMaxTotalConnections(params, 10); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setUseExpectContinue(params, false); 
    HttpConnectionParams.setStaleCheckingEnabled(params, true); 
    HttpConnectionParams.setConnectionTimeout(params, 30000); 
    HostnameVerifier hostnameVerifier= 
      org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; 
    HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); 
    SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory(); 
    socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier); 
    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(new Scheme("http",socketFactory, 80)); 
    schemeRegistry.register(new Scheme("https",socketFactory, 443)); 
     ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, schemeRegistry); 
     // Set verifier  
     client = new DefaultHttpClient(manager, params);  
    } 

Window7, HttpClient4Excepción: javax.net.ssl.SSLPeerUnverifiedException: Peer no autenticada

cuando es ejecutado: client.accessURL(url); Ocurre:

Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352) 
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128) 
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:397) 
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:495) 
    at org.apache.http.conn.scheme.SchemeSocketFactoryAdaptor.connectSocket(SchemeSocketFactoryAdaptor.java:62) 
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148) 
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150) 
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121) 
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:575) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) 

Respuesta

8

Este error se debe a que su servidor no tiene un certificado SSL válido. Por lo tanto, debemos decirle al cliente que use un TrustManager diferente. Aquí es un ejemplo de código:

SSLContext ctx = SSLContext.getInstance("TLS"); 
X509TrustManager tm = new X509TrustManager() { 

    public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { 
    } 

    public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { 
    } 

    public X509Certificate[] getAcceptedIssuers() { 
     return null; 
    } 
}; 
ctx.init(null, new TrustManager[]{tm}, null); 
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
ClientConnectionManager ccm = base.getConnectionManager(); 
SchemeRegistry sr = ccm.getSchemeRegistry(); 
sr.register(new Scheme("https", 443, ssf)); 

client = new DefaultHttpClient(ccm, base.getParams()); 
+5

¿De qué manera la eliminación de la seguridad de este extremo resolverá el problema en el otro extremo? Ese código de TrustManager ni siquiera se ajusta a la especificación. – EJP

+0

No veo tu punto. El problema proviene del lado del cliente, por lo tanto, solo tenemos que cambiarlo. ¿Qué línea de código TrustManager no cumple con la especificación? – bnguyen82

+5

'getAcceptedIssuers()' se especifica que nunca devuelve nulo. El código que has publicado es radicalmente inseguro. No resuelve ningún problema, simplemente crea otro problema, por ejemplo, vulnerabilidad a los ataques de hombre en el medio. – EJP

14

Certificado caducado era la causa de nuestra "javax.net.ssl.SSLPeerUnverifiedException: Peer no autenticado".

keytool -list -v -keystore filetruststore.ts

Enter keystore password: 
    Keystore type: JKS 
    Keystore provider: SUN 
    Your keystore contains 1 entry 
    Alias name: somealias 
    Creation date: Jul 26, 2012 
    Entry type: PrivateKeyEntry 
    Certificate chain length: 1 
    Certificate[1]: 
    Owner: CN=Unknown, OU=SomeOU, O="Some Company, Inc.", L=SomeCity, ST=GA, C=US 
    Issuer: CN=Unknown, OU=SomeOU, O=Some Company, Inc.", L=SomeCity, ST=GA, C=US 
    Serial number: 5011a47b 
    Valid from: Thu Jul 26 16:11:39 EDT 2012 until: Wed Oct 24 16:11:39 EDT 2012 
+0

¿Perdón por la pregunta "tonta", pero el certificado caducado estaba en el lado del servidor o del lado del cliente? – isapir

+0

@Igal Si recuerdo correctamente, el lado del servidor. – buzz3791

1

Esto también puede ocurrir si está intentando conectarse a través de HTTPS y el servidor no está configurado para manejar correctamente las conexiones SSL.

Revisaría la configuración SSL de tus servidores de aplicaciones y me aseguraré de que la certificación esté configurada correctamente.

+1

¿Qué se puede configurar mal? El certificado SSL funciona bien en el navegador. ¿Por qué no funciona con Java? ¿Por qué Java es tan especial? –

-5

si se encuentra en modo de desarrollo con certificado no válido, ¿por qué no simplemente establecer weClient.setUseInsecureSSL(true). funciona para mí

+0

Eso no es lo que pide el OP –

6

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 debe obtener el soporte de Enterprise de MOS (My Oracle Support). Este parche no es público

0

En mi caso, estaba usando un cliente JDK 8 y el servidor estaba usando cifrados antiguos inseguros. El servidor es Apache y he añadido esta línea a la configuración de Apache:

SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:!MEDIUM:!LOW:!SSLv2:!EXPORT 

Se debe utilizar una herramienta como esta para verificar la configuración de SSL está seguro: https://www.ssllabs.com/ssltest/analyze.html

2

usted puede conseguir este si está previsto por cliente "https" pero el servidor solo está ejecutando "http". Entonces, el servidor no espera hacer una conexión segura.

Cuestiones relacionadas