Ich verwende Java 6 und versuche HttpsURLConnection
, mithilfe eines Client-Zertifikats ein gegen einen Remote-Server zu erstellen .
Der Server verwendet ein selbstsigniertes Stammzertifikat und erfordert, dass ein kennwortgeschütztes Clientzertifikat vorgelegt wird. Ich habe das Server-Stammzertifikat und das Client-Zertifikat einem Standard-Java-Keystore hinzugefügt, den ich in /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts
(OSX 10.5) gefunden habe. Der Name der Keystore-Datei scheint darauf hinzudeuten, dass das Client-Zertifikat dort nicht eingehen soll.
Wie auch immer, das Hinzufügen des Stammzertifikats zu diesem Speicher löste das berüchtigte Problem javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed' problem.
Jetzt bin ich jedoch nicht mehr sicher, wie ich das Client-Zertifikat verwenden soll. Ich habe zwei Ansätze ausprobiert und keiner bringt mich irgendwohin.
Versuchen Sie zuerst und bevorzugt:
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
Ich habe versucht, die HttpsURLConnection-Klasse zu überspringen (nicht ideal, da ich HTTP mit dem Server sprechen möchte), und mache stattdessen Folgendes:
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
Ich bin mir nicht einmal sicher, ob das Client-Zertifikat hier das Problem ist.