628 Stimmen

Auflösen von javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX-Pfaderstellung fehlgeschlagen Fehler?

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 finden

javax.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());

4voto

YaDa Punkte 1245

Bei mir trat dieser Fehler ebenfalls auf, als ich versuchte, eine Verbindung zu einem Prozess hinter einem NGINX-Reverse-Proxy herzustellen, der SSL handhabte.

Es stellte sich heraus, dass das Problem ein Zertifikat war, bei dem die gesamte Zertifikatskette nicht verkettet war. Als ich Zwischenzertifikate hinzufügte, war das Problem gelöst.

Ich hoffe, das hilft.

4voto

Sharan Toor Punkte 71

Wenn Sie JDK 11 verwenden, befindet sich in dem Ordner kein JRE mehr. Der Speicherort für die Zertifizierungen ist jdk-11.0.11/lib/security/cacerts.

4voto

tk_ Punkte 14471

Aus Sicherheitsgründen sollten wir in unserer Implementierung keine selbstsignierten Zertifikate verwenden. Wenn es jedoch um die Entwicklung geht, müssen wir oft Testumgebungen mit selbstsignierten Zertifikaten verwenden. Ich habe versucht, dieses Problem programmatisch in meinem Code zu beheben und bin gescheitert. Durch das Hinzufügen des Zertifikats zum JRE-Trust-Store konnte ich das Problem jedoch beheben. Bitte finden Sie unten Schritte,

  1. Laden Sie die Standortbescheinigung herunter,

  2. Kopieren Sie das Zertifikat (z.B.: cert_file.cer) in das Verzeichnis $JAVA_HOME \Jre\Lib\Security

  3. Öffnen Sie CMD im Administrator und ändern Sie das Verzeichnis in $JAVA_HOME \Jre\Lib\Security

  4. Importieren Sie das Zertifikat mit dem folgenden Befehl in einen Vertrauensspeicher,

keytool -import -alias ca -datei cert_file.cer -Keystore-Zertifikate -storepass changeit

Wenn Sie eine Fehlermeldung erhalten, die besagt, dass keytool nicht erkannt wird, dann beziehen sich darauf.

Tipo ja wie unten

Vertrauen Sie diesem Zertifikat: [Ja]

  1. Versuchen Sie nun, Ihren Code auszuführen oder mit Java programmatisch auf die URL zuzugreifen.

Update

Wenn Ihr Anwendungsserver jboss ist, versuchen Sie, die folgende Systemeigenschaft hinzuzufügen

System.setProperty("org.jboss.security.ignoreHttpsHost","true");

Ich hoffe, das hilft!

3voto

Dave Richardson Punkte 4631

Dies scheint ein guter Ort zu sein, um eine weitere mögliche Ursache für die berüchtigte PKIX-Fehlermeldung zu dokumentieren. Nachdem ich viel zu lange damit verbracht habe, mir die Inhalte des Keystore und Truststore sowie verschiedene Java-Installationskonfigurationen anzusehen, wurde mir klar, dass mein Problem auf... einen Tippfehler zurückzuführen ist.

Der Tippfehler bedeutete, dass ich den Keystore auch als Truststore verwendet habe. Da die Root-CA meines Unternehmens nicht als eigenständiges Zertifikat im Keystore definiert war, sondern nur als Teil einer Zertifikatskette, und nirgendwo anders (z. B. in cacerts), erhielt ich immer wieder den PKIX-Fehler.

Nach einer fehlgeschlagenen Freigabe (dies ist eine Prod-Konfiguration, anderswo war sie in Ordnung) und zwei Tagen des Kopfkratzens habe ich den Tippfehler endlich entdeckt, und jetzt ist alles gut.

Ich hoffe, das hilft jemandem.

3voto

mons droid Punkte 968

Ich habe ein kleines Win32 (WinXP 32bit testet) dummes cmd (commandline) Skript geschrieben, das alle Java Versionen in Programmdateien sucht und ihnen ein Zertifikat hinzufügt. Das Passwort muss das Standard "changeit" sein oder man kann es selbst im Skript ändern :-)

@echo off

for /F  %%d in ('dir /B %ProgramFiles%\java') do (
    %ProgramFiles%\Java\%%d\bin\keytool.exe -import -noprompt -trustcacerts -file some-exported-cert-saved-as.crt -keystore %ProgramFiles%\Java\%%d\lib\security\cacerts -storepass changeit
)

pause

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X