Estoy usando Java 6 y estoy tratando de crear una HttpsURLConnection
contra un servidor remoto, usando un certificado de cliente.
El servidor utiliza un certificado raíz autofirmado y requiere que se presente un certificado de cliente protegido por contraseña. Agregué el certificado raíz del servidor y el certificado del cliente a un almacén de claves de Java predeterminado que encontré en /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts
(OSX 10.5). ¿El nombre del archivo del almacén de claves parece sugerir que el certificado del cliente no debe entrar allí?
De todos modos, agregar el certificado raíz a esta tienda resolvió el infame javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed' problem.
Sin embargo, ahora estoy atascado en cómo usar el certificado de cliente. He intentado dos enfoques y ninguno me lleva a ninguna parte.
Primero, y preferido, intente:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://somehost.dk:3049");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
// The last line fails, and gives:
// javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Intenté omitir la clase HttpsURLConnection (no es ideal ya que quiero hablar HTTP con el servidor) y hago esto en su lugar:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("somehost.dk", 3049);
InputStream inputstream = sslsocket.getInputStream();
// do anything with the inputstream results in:
// java.net.SocketTimeoutException: Read timed out
Ni siquiera estoy seguro de que el certificado de cliente sea el problema aquí.