Hola foro,
llevo bastante tiempo intentando programar una conexion Https con certificados autofirmados.. Haber si alguien me puede aclarar un par de dudas para rematar las clases.
Los clientes que utilizan las clases que posteo a continuacion tiene el certificado autofirmado añadido al cacerts (key store por defecto de la maquina virtual Java donde se encuentran los certificados de confianza).
De momento estoy intentando conectar a dicho un servidor mediante Https para descargar archivos xml. La duda que tengo es si la interfaz X509TrustManager permite realizar conexiones con certificados autofirmados que han sido autofirmados (Lo pregunto porque he leido en algunos sitios que no se puede, pero me surje la duda de que tal vez si se añaden al cacerts si lo permite).
Si se diera el caso de que dicha interfaz no permite las conexiones con certificados autofirmados entonces que interfaz debo utilizar???
Os dejo las clases que estoy implementando por si os sirven de ayuda:
public class Https {
//System.setProperty("javax.net.ssl.trustStore","tomcatKeystore");
//System.setProperty("javax.net.ssl.keyStore", "/usr/jdk1.5.0_11/jre/lib/security/cacerts");
//System.setProperty("javax.net.ssl.keyStorePassword","changeit");
// java -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=123456 MyApp
//System.setProperty("javax.net.ssl.trustStore","C:\\Archivos de Programa\\Java\\jre1.6.0_07\\lib\\security\\cacerts");
//System.setProperty("javax.net.ssl.trustStorePassword","changeit"");
//Para aceptar certificados que no estan en el keystore del cliente
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[] { new SimpleTrustManager1() }, null);
SSLSocketFactory ssf = sc.getSocketFactory();
System.
out.
println("Antes URL"); URL url
= new URL("https://loquesea.es"); HttpsURLConnection urlConection = (HttpsURLConnection) url.openConnection();
urlConection.setSSLSocketFactory(ssf);
urlConection.setHostnameVerifier(new SimpleHostnameVerifier());
//urlConection.connect();
System.
out.
println("Antes INPUTSTREAM"); System.
out.
println("Despues INPUTSTREAM");
System.
out.
println("Antes leer fichero"); File fichero
= new File("pruebas_ssl.xml"); byte[] bytes = new byte[1024];
int leidos;
while ((leidos = is.read(bytes)) != -1){
fos.write(bytes, 0, leidos);
}
fos.close();
is.close();
}
}
public class SimpleTrustManager1 implements X509TrustManager {
private Set<X509Certificate> certs = new HashSet<X509Certificate>();
public SimpleTrustManager1
() throws Exception { System.
out.
println("Entra en constructor SimpleTrustManager1()"); //Falta Cargar los certificados del Keystore en el atributo certs
String cacerts
= "C:\\Archivos de Programa\\Java\\jre1.6.0_07\\lib\\security\\cacerts"; ks.load(stream, "changeit".toCharArray());
stream.close();
//Comprobamos si cacerts se ha cargado correctamente en el KeyStore
// KeyStore.TrustedCertificateEntry certificateEntry = (KeyStore.TrustedCertificateEntry)ks.getCertificateAlias("alias_certificado");
//certs.addAll();
}
}
System.
out.
println("Entra en getAcceptedIssuers"); }
//try {
System.
out.
println("chain.length="+chain.
length); System.
out.
println("authType:" + authType
);
for (int i = 0; i < chain.length; i++) {
System.
out.
println("Entra en checkServerTrusted" + i
); System.
out.
println(prueba.
getName());
if (certs.contains(chain[i])) {
System.
out.
println("certs.contains(chain[i])"); trusted=true;
return;
}
}
if(!trusted){
int x
= JOptionPane.
showConfirmDialog(null,
"El servidor " + chain
[0].
getIssuerDN() + " no se puede verificar. " + "¿Desde realizar la conexión de todas formas?",
"TITULO",
JOptionPane.
YES_NO_OPTION); //throw new CertificateException("La clave no está en el trustore");
certs.add(chain[0]);
trusted=true;
System.
out.
println("Despues certs.add(chain[0]); "); }
else{
}
/**System.out.println("El servidor " + chain[0].getIssuerDN() + " no se puede verificar. " + "¿Desde realizar la conexión de todas formas?");
//Scanner s = new Scanner(System.in).useDelimiter("\r\n");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String linea = br.readLine();
System.out.println("Despues Scanner");
//String opcion = s.next();
System.out.println("opcion:" + linea);
if (!linea.equalsIgnoreCase("si")) {
throw new CertificateException("La clave no está en el trustore");
}
* */
/**
} catch (IOException ex) {
Logger.getLogger(SimpleTrustManager1.class.getName()).log(Level.SEVERE, null, ex);
}**/
}
}
}
public class SimpleHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify
(String hostname, SSLSession session
) { System.
out.
println("Host: "+hostname
); try {
System.
out.
println("DN:"+cert.
getIssuerDN()); } catch (SSLPeerUnverifiedException e) {
e.printStackTrace();
}
return true;
}
}
Cada clase se encuentra en un fichero por lo cual no se pueden compartir variables.
Cualquier aclaracion para encaminarme sera mas que agradecida.
Gracias de antemano.
Salu2.
alzehimer_cerebral