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.
Antworten:
Endlich gelöst;). Habe hier einen starken Hinweis (Gandalfs Antwort hat es auch ein bisschen berührt). Die fehlenden Links waren (meistens) der erste der folgenden Parameter, und bis zu einem gewissen Grad habe ich den Unterschied zwischen Keystores und Truststores übersehen.
Das selbstsignierte Serverzertifikat muss in einen Truststore importiert werden:
Diese Eigenschaften müssen festgelegt werden (entweder in der Befehlszeile oder im Code):
Arbeitsbeispielcode:
quelle
Obwohl dies nicht empfohlen wird, können Sie die SSL-Zertifikatsüberprüfung auch insgesamt deaktivieren:
quelle
Haben Sie die KeyStore- und / oder TrustStore-Systemeigenschaften festgelegt?
oder von mit dem Code
Gleiches gilt für javax.net.ssl.trustStore
quelle
Wenn Sie einen Webdienstaufruf mit dem Axis-Framework bearbeiten, gibt es eine viel einfachere Antwort. Wenn Ihr Client nur den SSL-Webdienst aufrufen und SSL-Zertifikatfehler ignorieren kann, geben Sie einfach diese Anweisung ein, bevor Sie Webdienste aufrufen:
System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory");
Es gelten die üblichen Haftungsausschlüsse, dass dies in einer Produktionsumgebung eine sehr schlechte Sache ist.
Ich habe das im Axis Wiki gefunden .
quelle
Für mich hat dies mit Apache HttpComponents ~ HttpClient 4.x funktioniert:
Die P12-Datei enthält das mit BouncyCastle erstellte Client-Zertifikat und den privaten Client-Schlüssel:
quelle
keyStore
ist, was den privaten Schlüssel und das Zertifikat enthält.Ich verwende das Apache Commons HTTP-Client-Paket, um dies in meinem aktuellen Projekt zu tun, und es funktioniert gut mit SSL und einem selbstsignierten Zertifikat (nachdem es wie erwähnt in cacerts installiert wurde). Bitte schauen Sie es sich hier an:
http://hc.apache.org/httpclient-3.x/tutorial.html
http://hc.apache.org/httpclient-3.x/sslguide.html
quelle
SSLContext
direkt verwenden, sodass Sie dies alles auf diese Weise konfigurieren können, anstatt es zu verwendenAuthSSLProtocolSocketFactory
.Ich denke, Sie haben ein Problem mit Ihrem Serverzertifikat, es ist kein gültiges Zertifikat (ich denke, dies ist, was "handshake_failure" in diesem Fall bedeutet):
Importieren Sie Ihr Serverzertifikat in Ihren Trustcacerts-Keystore in der JRE des Clients. Dies ist mit Keytool ganz einfach möglich :
quelle
Verwenden Sie den folgenden Code
oder
ist überhaupt nicht erforderlich. Außerdem müssen Sie keine eigene benutzerdefinierte SSL-Factory erstellen.
Ich habe auch das gleiche Problem festgestellt. In meinem Fall gab es ein Problem, bei dem die vollständige Zertifikatkette nicht in Truststores importiert wurde. Importieren Sie Zertifikate mit dem Dienstprogramm keytool direkt aus dem Stammzertifikat. Sie können auch die Datei cacerts im Editor öffnen und prüfen, ob die gesamte Zertifikatkette importiert wurde oder nicht. Überprüfen Sie anhand des Aliasnamens, den Sie beim Importieren von Zertifikaten angegeben haben, öffnen Sie die Zertifikate und prüfen Sie, wie viele darin enthalten sind. Die gleiche Anzahl von Zertifikaten sollte in der Cacerts-Datei enthalten sein.
Außerdem sollte die cacerts-Datei auf dem Server konfiguriert sein, auf dem Sie Ihre Anwendung ausführen. Die beiden Server authentifizieren sich gegenseitig mit öffentlichen / privaten Schlüsseln.
quelle