Bearbeiten: Ich habe versucht, die Frage und die akzeptierte Antwort in einer vorzeigbareren Form in meinem Blog .
Hier ist die Originalausgabe.
Ich erhalte diesen Fehler:
Ausführliche Meldung sun.security.validator.ValidatorException: PKIX-Pfad Erstellung fehlgeschlagen:
sun.security.provider.certpath.SunCertPathBuilderException: kann nicht auf keinen gültigen Zertifizierungspfad zum angeforderten Ziel findenjavax.net.ssl.SSLHandshakeException verursachen: sun.security.validator.ValidatorException: PKIX-Pfaderstellung fehlgeschlagen: sun.security.provider.certpath.SunCertPathBuilderException: Unfähig, einen gültigen Zertifizierungspfad für das angeforderte Ziel zu finden
Ich verwende Tomcat 6 als Webserver. Ich habe zwei HTTPS-Webanwendungen auf verschiedenen Tomcats an verschiedenen Ports, aber auf demselben Rechner installiert. Sagen wir App1 (Port 8443) und App2 (Port 443). App1 stellt eine Verbindung zu App2 her. Wenn App1 eine Verbindung zu App2 herstellt, erhalte ich den oben genannten Fehler. Ich weiß, dass dieser Fehler sehr häufig auftritt, und habe in verschiedenen Foren und auf verschiedenen Websites viele Lösungen gefunden. Ich habe den folgenden Eintrag in server.xml
der beiden Tomcats:
keystoreFile="c:/.keystore"
keystorePass="changeit"
Auf jeder Website wird derselbe Grund angegeben: Das von app2 ausgestellte Zertifikat befindet sich nicht im vertrauenswürdigen Speicher von app1 jvm. Dies scheint auch dann zuzutreffen, wenn ich versuche, die gleiche URL im IE-Browser aufzurufen, was auch funktioniert (mit der Meldung Es gibt ein Problem mit dem Sicherheitszertifikat dieser Website. Hier sage ich weiter zu dieser Website). Aber wenn dieselbe URL von einem Java-Client aufgerufen wird (in meinem Fall), erhalte ich den oben genannten Fehler. Um sie in den Truststore aufzunehmen, habe ich diese drei Optionen ausprobiert:
Option 1
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Option 2
Folgende Einstellung in der Umgebungsvariable
CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Option 3
Folgende Einstellung in der Umgebungsvariable
JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Ergebnis
Aber nichts funktionierte.
Was endlich funktionierte führt den Java-Ansatz aus, der in Wie behandelt man ungültige SSL-Zertifikate mit Apache HttpClient? von Pascal Thivent, d.h. die Ausführung des Programms InstallCert.
Aber dieser Ansatz ist gut für Devbox-Setup, aber ich kann es nicht in der Produktionsumgebung verwenden.
Ich frage mich, warum die drei oben genannten Ansätze nicht funktionieren, wenn ich die gleichen Werte in server.xml
des App2-Servers und dieselben Werte im Truststore durch Setzen von
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
im Programm App1.
Für weitere Informationen stelle ich die Verbindung folgendermaßen her:
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
if (conn instanceof HttpsURLConnection) {
HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();
conn1.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
reply.load(conn1.getInputStream());