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

1voto

Sergio Alonso Punkte 51

Meine Meinung dazu: In meinem Fall war cacerts kein Ordner, sondern eine Datei, und außerdem war sie in zwei Pfaden vorhanden Nachdem ich es entdeckt hatte, verschwand der Fehler, nachdem ich die .jks-Datei über diese Datei kopiert hatte.

# locate cacerts    
/usr/java/jdk1.8.0_221-amd64/jre/lib/security/cacerts
/usr/java/jre1.8.0_221-amd64/lib/security/cacerts

Nachdem ich sie gesichert habe, kopiere ich die .jks rüber.

cp /path_of_jks_file/file.jks /usr/java/jdk1.8.0_221-amd64/jre/lib/security/cacerts
cp /path_of_jks_file/file.jks /usr/java/jre1.8.0_221-amd64/lib/security/cacerts

Hinweis: Dieser einfache Trick behebt diesen Fehler bei einem Genexus-Projekt, obwohl file.jks auch in der server.xml-Datei des Tomcat enthalten ist.

1voto

Rock Punkte 954

Ich möchte mich zu Wort melden, da ich eine QEMU-Umgebung habe, in der ich Dateien in Java herunterladen muss. Es stellt sich heraus, dass die /etc/ssl/certs/java/cacerts in QEMU hat ein Problem, weil es nicht mit dem /etc/ssl/certs/java/cacerts in der Host-Umgebung. Die Host-Umgebung befindet sich hinter einem Firmen-Proxy, so dass die Java-Cacerts eine angepasste Version sind.

Wenn Sie eine QEMU-Umgebung verwenden, stellen Sie zunächst sicher, dass das Hostsystem auf Dateien zugreifen kann. Zum Beispiel können Sie versuchen dieses Skript auf Ihrem Host-Rechner zu sehen. Wenn das Skript auf dem Host-Rechner einwandfrei läuft, aber nicht in QEMU, dann haben Sie das gleiche Problem wie ich.

Um dieses Problem zu lösen, musste ich eine Sicherungskopie der Originaldatei in QEMU erstellen, die Datei in der Host-Umgebung in das QEMU-Chroot-Gefängnis kopieren und dann konnte Java Dateien normal in QEMU herunterladen.

Eine bessere Lösung wäre die Montage der /etc in die QEMU-Umgebung einbinden; ich bin mir jedoch nicht sicher, ob andere Dateien bei diesem Prozess beeinträchtigt werden. Daher habe ich beschlossen, diese hässliche, aber einfache Lösung zu verwenden.

0voto

Kendar Punkte 683

Bei der Betrachtung der Inhalte verschiedener Zertifikate und derjenigen, die durch das Standard-Opssl-Verfahren erzeugt wurden, ist mir aufgefallen, dass der AutorityKeyIdentifier für das Openssl-Root-Zertifikat auf sich selbst gesetzt wurde. Wahrscheinlich gibt es eine Möglichkeit, das zu umgehen... aber ich weiß es nicht...

Dann habe ich eine kleine Anwendung mit Java11 & BouncyCastle entwickelt, um Root-Zertifikate und -Schlüssel zu generieren, jetzt auf github: https://github.com/kendarorg/JavaCaCertGenerator

Die mit diesem Tool erzeugten Root-Zertifikate enthalten NICHT den AuthorityKeyIdentifier und können mit keytool direkt auf dem Cacert-Store installiert werden. Wenn ich dann die csr- und die ext-Datei mit den Domänennamen erstelle, wird dies gegen den Cacert-Speicher, der das Root-Zertifikat enthält, validiert und keine Handshake-Ausnahmen mehr!

Kann es sein, dass das cacert keinen rekursiven AuthorityKeyIdentifier zulässt? Ich weiß es nicht, aber ich würde eine Überprüfung zu schätzen wissen :)

0voto

Nubian Punkte 114

Ich habe dieses Problem auch.

Ich habe fast alles versucht, indem ich das SSL-Zertifikat zu .keystore hinzugefügt habe, aber es hat mit Java1_6_x nicht funktioniert. Bei mir hat es geholfen, wenn wir eine neuere Version von Java, Java1_8_x als JVM, verwenden.

-1voto

Harshavardhan Punkte 31

Nur ein kleiner Hacken. Aktualisieren Sie die URL in der Datei "hudson.model.UpdateCenter.xml" von https auf http

<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>http://updates.jenkins.io/update-center.json</url>
  </site>
</sites>

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