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

426

Bearbeiten: - Versucht, die Frage und die akzeptierte Antwort in meinem Blog auf präsentablere Weise zu formatieren

Hier ist die Originalausgabe.

Ich erhalte diesen Fehler:

Detaillierte Meldung sun.security.validator.ValidatorException: PKIX-Pfaderstellung fehlgeschlagen:
sun.security.provider.certpath.SunCertPathBuilderException: Es konnte kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden werden

Ursache javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX-Pfaderstellung fehlgeschlagen: sun.security.provider.certpath.SunCertPathBuilderException: Es konnte kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden werden

Ich benutze Tomcat 6 als Webserver. Ich habe zwei HTTPS-Webanwendungen auf verschiedenen Tomcats an verschiedenen Ports, aber auf demselben Computer installiert. Sag App1(port 8443)und App2(port 443). App1verbindet sich mit App2. Beim App1Herstellen einer Verbindung App2erhalte ich den obigen Fehler. Ich weiß, dass dies ein sehr häufiger Fehler ist, daher bin ich auf viele Lösungen in verschiedenen Foren und auf Websites gestoßen. Ich habe den folgenden Eintrag in server.xmlbeiden Tomcats:

keystoreFile="c:/.keystore" 
keystorePass="changeit"

Jede Site gibt den gleichen Grund an, warum sich das von app2 erteilte Zertifikat nicht im vertrauenswürdigen Speicher von app1 jvm befindet. Dies scheint auch zuzutreffen, wenn ich versucht habe, dieselbe URL im IE-Browser aufzurufen. Es funktioniert (beim Erwärmen liegt ein Problem mit dem Sicherheitszertifikat dieser Website vor. Hier sage ich, fahren Sie mit dieser Website fort). Aber wenn dieselbe URL vom Java-Client getroffen wird (in meinem Fall), erhalte ich den obigen Fehler. Um es in den Truststore zu stellen, habe ich diese drei Optionen ausprobiert:

Option 1

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Option2 Einstellung unten in der Umgebungsvariablen

CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

Option3 Einstellung unten in der Umgebungsvariablen

JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

Aber nichts hat funktioniert .

Was zuletzt funktioniert hat, ist die Ausführung des in Wie behandelt man ungültige SSL-Zertifikate mit Apache HttpClient vorgeschlagenen Java-Ansatzes ? von Pascal Thivent dh das Programm InstallCert ausführen.

Dieser Ansatz ist jedoch für das Devbox-Setup in Ordnung, aber ich kann ihn in der Produktionsumgebung nicht verwenden.

Ich frage mich , warum drei Ansätze oben genannten nicht funktioniert , wenn ich die gleichen Werte in erwähnt server.xmlvon app2Server und gleichen Werte in - Vertrauen durch Einstellung

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

im app1Programm.

Für weitere Informationen stelle ich folgende Verbindung 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());
M Sach
quelle
Mögliches Duplikat von HttpClient und SSL
Marquis of Lorne
Seltsamerweise bekam ich diesen Fehler bei der Kommunikation zwischen Clusterservern, die einzeln keine SSL-Probleme hatten. Sobald ich domainnamemeine RHEL-Server richtig eingestellt hatte, war das Problem behoben. Hoffe es hilft jemandem.
DavidG
Eine andere Sache zu überprüfen ist, dass Sie die neueste Version von Java haben - ich habe aus diesem Grund einen ähnlichen Fehler erhalten.
Redzarf
stackoverflow.com/questions/2893819/… - auch relevant und eine fantastische Antwort.
Siddhartha

Antworten:

406

Sie müssen das Zertifikat für App2 zur Truststore-Datei der verwendeten JVM unter hinzufügen %JAVA_HOME%\lib\security\cacerts.

Zuerst können Sie überprüfen, ob sich Ihr Zertifikat bereits im Truststore befindet, indem Sie den folgenden Befehl ausführen: keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"(Sie müssen kein Kennwort angeben )

Wenn Ihr Zertifikat fehlt, können Sie es herunterladen, indem Sie es mit Ihrem Browser herunterladen und mit dem folgenden Befehl zum Truststore hinzufügen:

keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>

Nach dem Import können Sie den ersten Befehl erneut ausführen, um zu überprüfen, ob Ihr Zertifikat hinzugefügt wurde.

Sun / Oracle-Informationen finden Sie hier .

SimonSez
quelle
6
Sie müssen den vollständigen Pfad verwenden, z. B. c: \ java \ jdk \ lib \ security \ cacerts
SimonSez
48
Wie SimonSez sagte, brauchen Sie kein Passwort, aber wenn Sie es wollen, ist das Standardpasswort "changeit".
Felix
16
Außerdem müssen Sie unter Windows das Terminal als Administrator ausführen, da sonst die Fehlermeldung angezeigt wird, keytool error: java.io.FileNotFoundException ... (Access is denied)wenn Sie versuchen, Ihr Zertifikat zu importieren.
Felix
2
Ah @SimonSez du bist mein Gott. Um dies zu ergänzen, müssen Sie den Speicherort und das Kennwort des Vertrauensspeichers angeben, wie von @M Sach angegeben, damit es funktioniert.
BudsNanKis
2
Es gab weiterhin Probleme mit Java 1.8. Erforderlich, um Zertifikat wie beschrieben hinzuzufügen und Java <1.8
Tom Howard
180

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX-Pfaderstellung fehlgeschlagen: sun.security.provider.certpath.SunCertPathBuilderException: Es konnte kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden werden

• Als ich den Fehler erhielt, habe ich versucht, die Bedeutung des Ausdrucks bei Google herauszufinden. Dieses Problem tritt auf, wenn ein Server sein HTTPS-SSL-Zertifikat ändert und unsere ältere Java-Version die Stammzertifizierungsstelle (CA) nicht erkennt. .

• Wenn Sie in Ihrem Browser auf die HTTPS-URL zugreifen können, können Sie Java aktualisieren, um die Stammzertifizierungsstelle zu erkennen.

• Wechseln Sie in Ihrem Browser zu der HTTPS-URL, auf die Java nicht zugreifen konnte. Klicken Sie auf die HTTPS-Zertifikatkette (im Internet Explorer befindet sich ein Schlosssymbol), und klicken Sie auf die Sperre, um das Zertifikat anzuzeigen.

• Gehen Sie zu "Details" des Zertifikats und "In Datei kopieren". Kopieren Sie es im Base64- Format (.cer) . Es wird auf Ihrem Desktop gespeichert.

• Installieren Sie das Zertifikat und ignorieren Sie alle Warnungen.

• Auf diese Weise habe ich die Zertifikatinformationen der URL gesammelt, auf die ich zugreifen wollte.

Jetzt musste ich meine Java-Version erstellen, um über das Zertifikat Bescheid zu wissen, damit es sich nicht weigert, die URL zu erkennen. In diesem Zusammenhang muss ich erwähnen, dass ich gegoogelt habe, dass Stammzertifikatinformationen standardmäßig im Speicherort \ jre \ lib \ security von JDK verbleiben und das Standardkennwort für den Zugriff lautet: changeit.

Um die Cacerts-Informationen anzuzeigen, gehen Sie wie folgt vor:

• Klicken Sie auf Start Button -> Run

• Geben Sie cmd ein. Die Eingabeaufforderung wird geöffnet (möglicherweise müssen Sie sie als Administrator öffnen).

• Gehen Sie in Ihr Java/jreX/binVerzeichnis

• Geben Sie Folgendes ein

keytool -list -keystore D: \ Java \ jdk1.5.0_12 \ jre \ lib \ security \ cacerts

Es enthält die Liste der aktuellen Zertifikate, die im Keystore enthalten sind. Es sieht ungefähr so ​​aus:

C: \ Dokumente und Einstellungen \ NeelanjanaG> keytool -list -keystore D: \ Java \ jdk1.5.0_12 \ jre \ lib \ security \ cacerts

Geben Sie das Keystore-Passwort ein: changeit

Keystore-Typ: jks

Keystore-Anbieter: SUN

Ihr Keystore enthält 44 Einträge

verisignclass3g2ca, 26. März 2004, trustedCertEntry,

Zertifikatfingerabdruck (MD5): A2: 33: 9B: 4C: 74: 78: 73: D4: 6C: E7: C1: F3: 8D: CB: 5C: E9

entrustclientca, 9. Januar 2003, trustedCertEntry,

Zertifikatfingerabdruck (MD5): 0C: 41: 2F: 13: 5B: A0: 54: F5: 96: 66: 2D: 7E: CD: 0E: 03: F4

thawtepersonalbasicca, 13. Februar 1999, trustedCertEntry,

Zertifikatfingerabdruck (MD5): E6: 0B: D2: C9: CA: 2D: 88: DB: 1A: 71: 0E: 4B: 78: EB: 02: 41

addtrustclass1ca, 1. Mai 2006, trustedCertEntry,

Zertifikatfingerabdruck (MD5): 1E: 42: 95: 02: 33: 92: 6B: B9: 5F: C0: 7F: DA: D6: B2: 4B: FC

verisignclass2g3ca, 26. März 2004, trustedCertEntry,

Zertifikatfingerabdruck (MD5): F8: BE: C4: 63: 22: C9: A8: 46: 74: 8B: B8: 1D: 1E: 4A: 2B: F6

• Jetzt musste ich das zuvor installierte Zertifikat in die Cacerts aufnehmen.

• Gehen Sie dazu wie folgt vor:

keytool –import –noprompt –trustcacerts –alias ALIASNAME -file FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass PASSWORD

Wenn Sie Java 7 verwenden:

keytool –importcert –trustcacerts –alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit

• Anschließend werden die Zertifikatinformationen zur Cacert-Datei hinzugefügt.

Es ist die Lösung, die ich für die oben erwähnte Ausnahme gefunden habe !!

NDeveloper
quelle
5
Was machen Sie, wenn das Zertifikat abläuft? Alles wiederholen (jährlich)?
ggkmath
7
Gibt es eine Möglichkeit, dies programmgesteuert zu tun?
Meshulam Silk
1
Für Leute, die mit dem PKIX-Fehler "Pfad verkettet sich nicht mit einem der Vertrauensanker" befassen, hat diese Lösung dieses Problem für mich leider nicht gelöst.
IcedDante
3
Eine Frage - Ist der Aliasname die Webadresse, für die wir das Zertifikat importieren? Wenn die URL beispielsweise domain.site.com/pages/service.asmx lautet, sollte der Alias ​​domain.site.com oder die vollständige URL (domain.site.com/pages/service.asmx) sein oder auch das Präfix http vorangestellt werden : // oder ist es nur ein beliebiger Name?
Nanosoft
1
Pfad: \ lib \ security> keytool -import -noprompt -trustcacerts -alias webCert -file webCertResource.cer -keystore c: / Users / Jackie / Desktop -storepass changeit Ich erhalte die Meldung "Das System kann die angegebene Datei nicht finden"
Jesse
46

Wie man es in Tomcat 7 macht

Ich wollte ein selbstsigniertes Zertifikat in einer Tomcat-App unterstützen, aber das folgende Snippet funktionierte nicht

import java.io.DataOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HTTPSPlayground {
    public static void main(String[] args) throws Exception {

        URL url = new URL("https:// ... .com");
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        httpURLConnection.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());

        String serializedMessage = "{}";
        wr.writeBytes(serializedMessage);
        wr.flush();
        wr.close();

        int responseCode = httpURLConnection.getResponseCode();
        System.out.println(responseCode);
    }
}

Dies hat mein Problem gelöst:

1) Laden Sie die .crtDatei herunter

echo -n | openssl s_client -connect <your domain>:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/<your domain>.crt
  • durch <your domain>deine Domain ersetzen (zB jossef.com)

2) Wenden Sie die .crtDatei im Java- cacertsZertifikatspeicher an

keytool -import -v -trustcacerts -alias <your domain> -file ~/<your domain>.crt -keystore <JAVA HOME>/jre/lib/security/cacerts -keypass changeit -storepass changeit
  • durch <your domain>deine Domain ersetzen (zB jossef.com)
  • Ersetzen Sie <JAVA HOME>durch Ihr Java-Home-Verzeichnis

3) Hack es

Obwohl ich mein Zertifikat in Javaden Standardzertifikatsspeichern installiert habe , ignoriert Tomcat dies (anscheinend ist es nicht für die Verwendung der Standardzertifikatspeicher von Java konfiguriert).

Um dies zu hacken, fügen Sie irgendwo in Ihrem Code Folgendes hinzu:

String certificatesTrustStorePath = "<JAVA HOME>/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);

// ...
Jossef Harush
quelle
4
Schritt 2 hat mir mit SpringBoot und Tomcat 7 geholfen. Vielen Dank.
Tim Perry
Muss ich Keytool von Java verwenden, das von Tomcat verwendet wird? Auf einem Server kann ich viele Java
Vikifor
@ Vikifor ja. Sie können es auch für alle auf Ihrem System installierten Java-Verzeichnisse ausführen
Jossef Harush
1
Das hat funktioniert! Vielen Dank @JossefHarush für diese nützliche Antwort!
Tom Taylor
1
Mein Problem wurde behoben, nachdem ich das Codesegment von @Jossef Harush zu meinem Code hinzugefügt hatte.
Chamod Pathirana
10

In meinem Fall bestand das Problem darin, dass der Webserver nur das Zertifikat und die Zwischenzertifizierungsstelle sendete, nicht die Stammzertifizierungsstelle. Das Hinzufügen dieser JVM-Option löste das Problem:-Dcom.sun.security.enableAIAcaIssuers=true

Unterstützung für die Zugriffsmethode caIssuers der Erweiterung Authority Information Access ist verfügbar. Es ist aus Kompatibilitätsgründen standardmäßig deaktiviert und kann aktiviert werden, indem die Systemeigenschaft com.sun.security.enableAIAcaIssuersauf den Wert true gesetzt wird.

Wenn true festgelegt ist, verwendet die PKIX-Implementierung von CertPathBuilder von Sun die Informationen in der AIA-Erweiterung eines Zertifikats (zusätzlich zu den angegebenen CertStores), um das ausstellende CA-Zertifikat zu finden, sofern es sich um einen URI vom Typ ldap, http oder ftp handelt.

Quelle

Guillaume
quelle
Dies hat mein Problem tatsächlich gelöst, danke!
Luís Silva
6

Ein weiterer Grund könnte eine veraltete Version von JDK sein. Ich habe jdk Version 1.8.0_60 verwendet. Durch einfaches Aktualisieren auf die neueste Version wurde das Zertifikatsproblem behoben.

Ali Ismayilov
quelle
2
Ich hatte auch das gleiche Problem. Das Aufrufen einer API mit einem Lets Encrypt-Zertifikat funktioniert möglicherweise nicht mit älteren Java-Versionen, da es von den vertrauenswürdigen Root-Zertifizierungsstellen nicht erkannt wird. Durch das Aktualisieren von Java wird dieses Problem behoben.
Hertg
5

Meine Cacerts-Datei war völlig leer. Ich habe dieses Problem gelöst, indem ich die cacerts-Datei von meinem Windows-Computer (der Oracle Java 7 verwendet) kopiert und auf meine Linux-Box (OpenJDK) übertragen habe.

cd %JAVA_HOME%/jre/lib/security/
scp cacerts mylinuxmachin:/tmp

und dann auf dem Linux-Rechner

cp /tmp/cacerts /etc/ssl/certs/java/cacerts

Es hat bisher großartig funktioniert.

Ryan Shillington
quelle
1
Dies funktioniert wunderbar, wenn das Problem darin besteht, dass Sie eine ältere Version von Java verwenden, die nicht über die neuesten Zertifikate verfügt.
Atripathi
@atripathi wie wäre es mit einem Mac?
iOSAndroidWindowsMobileAppsDev
Bei Ihrer Java-Installation ist ein schwerwiegender Fehler aufgetreten, wenn die cacerts-Datei leer war. Sie sollten alles neu installiert haben.
Marquis von Lorne
Vielleicht, aber diese Lösung hat funktioniert und danach war nichts mehr falsch.
Ryan Shillington
5

Für mich trat dieser Fehler auch beim Versuch auf, eine Verbindung zu einem Prozess hinter einem NGINX-Reverse-Proxy herzustellen, der das SSL handhabte.

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

Hoffe das hilft.

YaDa
quelle
Das sieht so aus, wie ich es habe. Können Sie erklären, wie und wo Sie die Zwischenzertifikate hinzugefügt haben? Ich benutze httpd Reverse Proxy und nicht NGINX.
Asaf Magen
Dies half mir in meinem Fall, weil ich httpd: access.redhat.com/solutions/43575
Asaf Magen
Bei nginx werden nur .key- und .pem-Dateien für die SSL-Konfiguration verwendet. Zuerst konvertieren Sie .crt in .pem (einfach: cp yourfile.crt yourfile.pem) und dann für die SSL-Zertifikatskette: Sie hängen die .cer-Datei an die letzte von .pem an (cat yourfile.cer >> yourfile.pem)
Thế Anh Nguyễn
5

Mit Tomcat 7 unter Linux war dies der Trick.

String certificatesTrustStorePath = "/etc/alternatives/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Unter Linux $JAVA_HOMEist nicht immer eingerichtet, zeigt aber in der Regel /etc/alternatives/jreauf$JAVA_HOME/jre

Cedric Simon
quelle
5

Der folgende Code funktioniert für mich:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class TrustAnyTrustManager implements X509TrustManager {

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}

HttpsURLConnection conn = null;
            URL url = new URL(serviceUrl);
            conn = (HttpsURLConnection) url.openConnection();
             SSLContext sc = SSLContext.getInstance("SSL");  
             sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());  

             conn.setSSLSocketFactory(sc.getSocketFactory());
Sandip S.
quelle
5
Dieser Code ist völlig unsicher und sollte nicht verwendet werden.
Marquis von Lorne
@ user207421 Warum ist es unsicher? Was passiert im Code kurz.
Govinda Sakhare
Dadurch werden alle Zertifikatsüberprüfungen übersprungen. Grundsätzlich kann jedes Zertifikat akzeptiert werden. Die Funktionsweise von Zertifikaten besteht darin, dass bei verschiedenen Zertifizierungsstellen ein Stammzertifikat (im wahrsten Sinne des Wortes) physisch geschützt ist. Dieses Zertifikat wird dann verwendet, um andere sekundäre Zertifikate auszustellen, die bis zur Stammzertifizierungsstelle validiert werden können. Dies überspringt alle Upstream-Prüfungen, was bedeutet, dass ich jedes SSL-Zertifikat (auch selbst generiert) einsenden kann und Ihre Anwendung es als sicher akzeptiert, obwohl meine Identität als URL nicht überprüft wird.
Scott Taylor
4

Ich habe verwendet, jdk1.8.0_171als ich vor dem gleichen Problem stand. Ich habe hier die Top-2-Lösungen ausprobiert (Hinzufügen eines Zertifikats mit Keytool und einer anderen Lösung, die einen Hack enthält), aber sie haben bei mir nicht funktioniert.

Ich habe mein JDK auf aktualisiert 1.8.0_181und es hat wie ein Zauber funktioniert.

avp
quelle
2

Ich habe ein kleines dummes Win32-Skript (WinXP 32bit Testet) geschrieben, das nach allen Java-Versionen in Programmdateien sucht und ihnen ein Zertifikat hinzufügt. Das Passwort muss das Standard "changeit" sein oder 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
Mons Droide
quelle
2

Für MacOS X unten ist der genaue Befehl, der für mich funktioniert hat, wo ich mit doppeltem Bindestrich in der Option 'importcert' versuchen musste, was funktionierte:

sudo keytool -–importcert -file /PathTo/YourCertFileDownloadedFromBrowserLockIcon.crt -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/security/cacerts -alias "Cert" -storepass changeit
Abhishek
quelle
2

Für mich hat die erkannte Lösung aus diesem Beitrag nicht funktioniert: https://stackoverflow.com/a/9619478/4507034 .

Stattdessen konnte ich das Problem lösen, indem ich die Zertifizierung in die vertrauenswürdigen Zertifizierungen meines Computers importierte.

Schritte:

  1. Gehen Sie zu der URL (z. B. https://localhost:8443/yourpath), unter der die Zertifizierung nicht funktioniert.
  2. Exportieren Sie die Zertifizierung wie im genannten Beitrag beschrieben.
  3. Öffnen Sie auf Ihrem Windows-Computer: Manage computer certificates
  4. Gehe zu Trusted Root Certification Authorities->Certificates
  5. Importieren Sie hier Ihre your_certification_name.cerDatei.
Radu Linu
quelle
1

Verwenden Sie den Befehl "ps -ef | grep tomcat", wenn Tomcat auf einem Ubuntu-Server ausgeführt wird, um herauszufinden, welches Java verwendet wird:

Stichprobe:

/home/mcp01$ **ps -ef |grep tomcat**
tomcat7  28477     1  0 10:59 ?        00:00:18 **/usr/local/java/jdk1.7.0_15/bin/java** -Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties -Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat7/endorsed -classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start
1005     28567 28131  0 11:34 pts/1    00:00:00 grep --color=auto tomcat

Dann können wir gehen zu: cd /usr/local/java/jdk1.7.0_15/jre/lib/security

Die Standard- Cacerts- Datei befindet sich hier. Fügen Sie das nicht vertrauenswürdige Zertifikat ein.

Orakel
quelle
1

Aus Sicherheitsgründen sollten wir bei unserer Implementierung keine selbstsignierten Zertifikate verwenden. Wenn es jedoch häufig um die Entwicklung geht, müssen wir Testumgebungen verwenden, die selbstsignierte Zertifikate erhalten haben. Ich habe versucht, dieses Problem programmgesteuert in meinem Code zu beheben, aber es schlägt fehl. Durch Hinzufügen des Zertifikats zum jre Trust-Store wurde mein Problem behoben. Nachfolgend finden Sie Schritte,

  1. Laden Sie das Site-Zertifikat herunter.

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

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

  4. Importieren Sie das Zertifikat mit dem folgenden Befehl in einen Trust Store.

keytool -import -alias ca -file cert_file.cer -keystore cacerts -storepass changeit

Wenn Sie eine Fehlermeldung erhalten, dass Keytool nicht erkennbar ist, lesen Sie dies bitte .

Tippe ja wie unten

Vertrauen Sie diesem Zertifikat: [Ja]

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

Aktualisieren

Wenn Ihr App-Server jboss ist, versuchen Sie, die folgenden Systemeigenschaften hinzuzufügen

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

Hoffe das hilft!

tk_
quelle
1

VERWENDBARE LÖSUNG (Alpine Linux)

Um dieses Problem in unseren Anwendungsumgebungen beheben zu können, haben wir Linux-Terminalbefehle wie folgt vorbereitet:

cd ~

Generiert eine Zertifikatdatei im Home-Verzeichnis.

apk add openssl

Dieser Befehl installiert openssl unter alpine Linux. Sie können geeignete Befehle für andere Linux-Distributionen finden.

openssl s_client -connect <host-dns-ssl-belongs> < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt

Generierte die benötigte Zertifizierungsdatei.

sudo $JAVA_HOME/bin/keytool -import -alias server_name -keystore $JAVA_HOME/lib/security/cacerts -file public.crt -storepass changeit -noprompt

Wendet die generierte Datei mit dem Programm 'keytool' auf die JRE an.

Hinweis: Bitte ersetzen Sie Ihr DNS durch<host-dns-ssl-belongs>

Hinweis 2: Bitte beachten Sie, dass -nopromptdie Bestätigungsmeldung nicht angezeigt wird (Ja / Nein) und der -storepass changeitParameter die Kennwortabfrage deaktiviert und das erforderliche Kennwort bereitstellt (Standard ist 'changeit'). Mit diesen beiden Eigenschaften können Sie diese Skripts in Ihren Anwendungsumgebungen verwenden, z. B. zum Erstellen eines Docker-Images.

Hinweis 3 Wenn Sie Ihre App über Docker bereitstellen , können Sie die geheime Datei einmal generieren und in Ihre Anwendungsprojektdateien einfügen. Sie müssen es nicht immer wieder generieren.

Bahadir Tasdemir
quelle
0

Ich habe auch dieses Problem.

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

Nubian
quelle
1
Auch für mich. Ein Update von Java 1.8.0_91 auf 1.8.0_121 löste das Problem. Ich habe die Ausnahme mit Apache HTTPClient erhalten.
Devabc
Ich habe immer noch dieses Problem mit der Oauth2-Authentifizierung
Sofiane
0

Ich hatte dieses Problem mit Android Studio, als ich hinter einem Proxy stehe. Ich habe Crashlytics verwendet, das versucht, die Zuordnungsdatei während eines Builds hochzuladen.

Ich habe das fehlende Proxy-Zertifikat zum Truststore unter hinzugefügt /Users/[username]/Documents/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/security/cacerts

mit folgendem Befehl: keytool -import -trustcacerts -keystore cacerts -storepass [password] -noprompt -alias [alias] -file [my_certificate_location]

Zum Beispiel mit dem Standardkennwort für den Truststore keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias myproxycert -file /Users/myname/Downloads/MyProxy.crt

Verkabelung
quelle
0

Nur ein kleiner Hack. 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>
Harshavardhan
quelle
0

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

Wenn Sie eine QEMU-Umgebung verwenden, stellen Sie sicher, dass das Hostsystem zuerst auf Dateien zugreifen kann. Zum Beispiel können Sie dieses Skript ausprobieren auf Ihrem Host-Computer . Wenn das Skript auf dem Host-Computer einwandfrei ausgeführt wird, jedoch nicht in QEMU, 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 Hostumgebung in das QEMU-Chroot-Gefängnis kopieren und dann konnte Java Dateien normalerweise in QEMU herunterladen.

Eine bessere Lösung wäre das Einbinden /etcin die QEMU-Umgebung. Ich bin mir jedoch nicht sicher, ob andere Dateien von diesem Prozess betroffen sind. Also entschied ich mich für diese hässliche, aber einfache Lösung.

Felsen
quelle
0

Dies scheint ein ebenso guter Ort zu sein, um einen weiteren möglichen Grund für die berüchtigte PKIX-Fehlermeldung zu dokumentieren. Nachdem ich viel zu lange den Keystore- und Truststore-Inhalt und verschiedene Java-Installationskonfigurationen durchgesehen hatte, stellte ich fest, dass mein Problem auf ... einen Tippfehler zurückzuführen war.

Der Tippfehler bedeutete, dass ich auch den Keystore als Truststore verwendete. Da die Stammzertifizierungsstelle meines Unternehmens nicht als eigenständiges Zertifikat im Keystore definiert wurde, sondern nur als Teil einer Zertifikatskette und nirgendwo anders definiert wurde (z. B. Zertifikate), wurde der PKIX-Fehler immer wieder angezeigt.

Nach einer fehlgeschlagenen Veröffentlichung (dies ist eine Produktkonfiguration, woanders war es in Ordnung) und zwei Tagen Kopfkratzen sah ich endlich den Tippfehler, und jetzt ist alles in Ordnung.

Hoffe das hilft jemandem.

Dave Richardson
quelle
-1

Fügen Sie dies Ihrem Code hinzu:

TrustManager[] trustAllCerts = new TrustManager[]{
           new X509TrustManager() {
               @Override
               public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                   return new X509Certificate[0];
               }

               @Override
               public void checkClientTrusted(
                       java.security.cert.X509Certificate[] certs, String authType) {
               }

               @Override
               public void checkServerTrusted(
                       java.security.cert.X509Certificate[] certs, String authType) {
               }
           }
       };

       try {
           SSLContext sc = SSLContext.getInstance("SSL");
           sc.init(null, trustAllCerts, new java.security.SecureRandom());
           HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
       } catch (GeneralSecurityException e) {
       }

quelle
1
Nur-Code-Antworten werden auf dieser Website im Allgemeinen verpönt. Könnten Sie bitte Ihre Antwort bearbeiten, um einige Kommentare oder Erklärungen zu Ihrem Code aufzunehmen? Erklärungen sollten Fragen beantworten wie: Was macht es? Wie macht es das? Wohin geht es? Wie löst es das Problem von OP?
Mypetlion
1
Fügen Sie dies zu Ihrer Code- Nr. hinzu . Fügen Sie dies nicht zu Ihrem Code hinzu . Wenn Sie auf diese Weise einen SSLContext erstellen, werden alle Sicherheitsüberprüfungen entfernt, die die Identität des Servers überprüfen, zu dem Sie eine Verbindung herstellen. Die Antwort auf das Problem des Verlusts Ihrer Schlüssel besteht darin, NICHT alle Schlösser von allem zu entfernen, was Sie besitzen.
Andrew Henle