2011-05-17 89 views
28

¿Hay alguna manera para que los sockets SSL java estándar deshabiliten la verificación del nombre de host para las conexiones ssl con una propiedad? La única forma que encontré hasta ahora es escribir un verificador de nombre de host que devuelve verdadero todo el tiempo.Java SSL: cómo deshabilitar la verificación del nombre de host

Weblogic ofrece esta posibilidad, es posible desactivar la verificación de nombre de host con la siguiente propiedad:

-Dweblogic.security.SSL.ignoreHostnameVerify

+1

Bueno, la suya es la solución más limpia que se me ocurre; ¿Hay algo malo con eso? – Piskvor

+1

bueno, solo quiere deshabilitar el cheque y hacer esto sin cambios de código. Normalmente tiene muchas propiedades para controlar las conexiones SSL, pero aparentemente no en este caso ... – paweloque

+0

bueno, usted * podría * hacer un verificador de nombre de host * fábrica * que verificaría su propiedad personalizada y devolvería el verificador simulado "siempre-ok" si está configurado, o el verificador predeterminado si no; sin embargo, esto realmente no resuelve el problema, ¿verdad? – Piskvor

Respuesta

3

No hay verificación de nombre de host en sockets SSL estándar de Java o de hecho SSL, por eso no puede establecerlo en ese nivel. La verificación del nombre de host es parte de HTTPS (RFC 2818): por eso se manifiesta como javax.net.ssl.HostnameVerifier, que se aplica a una HttpsURLConnection.

+0

Eso suena razonable, sin embargo, ¿por qué weblogic proporciona un cambio así y por qué no hay tal propiedad en el nivel HttpsURLConnection? – paweloque

+0

@lewap ¿Supongo que estas son preguntas retóricas? No puedo responder preguntas sobre WebLogic, ni sobre por qué el JDK es como es. La cosa de WebLogic me parece un agujero de seguridad, no lo quisiera en el JDK. – EJP

+3

no son para nada retóricos, intento entender cómo funciona SSL y comprender las diferencias entre jdk y weblogic. Tal vez haya una razón para eso. – paweloque

23

Debe ser posible crear la costumbre java agent que anula por defecto HostnameVerifier:

import javax.net.ssl.*; 
import java.lang.instrument.Instrumentation; 

public class LenientHostnameVerifierAgent { 
    public static void premain(String args, Instrumentation inst) { 
     HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 
      public boolean verify(String s, SSLSession sslSession) { 
       return true; 
      } 
     }); 
    } 
} 

Entonces sólo tiene que añadir --javaagent:LenientHostnameVerifierAgent.jar a los argumentos de inicio del programa Java.

+1

Esta podría ser una gran manera de manejarlo, pero estoy lidiando con el cliente http de Apache. ¿Cómo podría crear un javaagent para establecer 'SSLSocketFactory.setHostnameVerifier (new AllowAllHostnameVerifier())'? –

+0

@ usuario final, exactamente de la misma manera que en esta respuesta. – Vadzim

3

También tuve el mismo problema al acceder a los servicios web RESTful. Y me su con el siguiente código para resolver el problema:

public class Test { 
    //Bypassing the SSL verification to execute our code successfully 
    static { 
     disableSSLVerification(); 
    } 

    public static void main(String[] args) {  
     //Access HTTPS URL and do something  
    } 
    //Method used for bypassing SSL verification 
    public static void disableSSLVerification() { 

     TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { 
      public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 

      public void checkClientTrusted(X509Certificate[] certs, String authType) { 
      } 

      public void checkServerTrusted(X509Certificate[] certs, String authType) { 
      } 

     } }; 

     SSLContext sc = null; 
     try { 
      sc = SSLContext.getInstance("SSL"); 
      sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
     } catch (KeyManagementException e) { 
      e.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } 
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 

     HostnameVerifier allHostsValid = new HostnameVerifier() { 
      public boolean verify(String hostname, SSLSession session) { 
       return true; 
      } 
     };  
     HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);   
    } 
} 

Me funcionó. ¡¡intentalo!!

+0

Esta solución no funcionó para mí. – seanmcl

+3

Esto inseguramente confía en todos los certificados, pero no omite la verificación de nombre de host, por lo que no responde la pregunta. – EJP

Cuestiones relacionadas