Mostrando las entradas con la etiqueta ssl. Mostrar todas las entradas
Mostrando las entradas con la etiqueta ssl. Mostrar todas las entradas

lunes, 28 de junio de 2010

HTTPS hostname wrong

Al acceder a una URL como en el post anterior pero utilizando la dirección IP se me pesentó el siguiente error:

java.io.IOException: HTTPS hostname wrong: should be <10.1.84.139>

Encontré en algún lado que para poder pasar esa verificación de hostname se puede crear un HostNameVerifier y setearlo como el que se va a usar por defecto en la aplicación:
HostnameVerifier hv = new HostnameVerifier() {
  public boolean verify(String urlHostName, SSLSession session){
    return true;
  }
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
Lo que no entendí es por qué falla la verificación, si al poner la siguiente línea dentro del método verify:
System.out.println("HostName: " + urlHostName + " sessionHost: " + session.getPeerHost());

El resultado es:
HostName: 10.1.84.139 sessionHost: 10.1.84.139

martes, 2 de marzo de 2010

Java: URL's seguras con certificados no confiables

Para acceder a una URL segura desde Java, se hace el mismo procedimiento que con una URL no segura:

URL url = new URL("https://www.urlsegura.com");
URLConnection conn = url.openConnection();

BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String linea;

while ((linea = in.readLine()) != null) 
  System.out.println(linea);
in.close();
Pero si esa URL segura tiene un certificado no confiable, el acceso a esa URL va a fallar, generando un error similar al siguiente:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Entonces lo que hay que hacer es instalar un TrustManager que no valide los certificados, en el Contexto SSL.
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());
  HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

} catch (Exception e) { }

Una vez hecho esto ya podemos hacer lo del código de arriba sin que nos falle por certificados de seguridad.