Bearbeiten: - Es wurde versucht, die Frage und die akzeptierte Antwort bei mir auf ansehnlichere Weise zu formatieren Blog
Hier ist die ursprüngliche Ausgabe.
Ich erhalte diesen Fehler:
detaillierte Meldung Sun.security.validator.ValidatorException: PKIX-Pfadaufbau fehlgeschlagen:
Sun.security.provider.certpath.SunCertPathBuilderException: Es wurde kein gültiger Zertifizierungspfad für das angeforderte Ziel gefundenjavax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX-Pfadaufbau fehlgeschlagen: Sun.security.provider.certpath.SunCertPathBuilderException: Es wurde kein gültiger Zertifizierungspfad für das angeforderte Ziel gefunden
Ich benutze Tomcat 6 als Webserver. Ich habe zwei HTTPS-Webanwendungen auf verschiedenen Tomcats an verschiedenen Ports, aber auf demselben Computer installiert. Sagen Sie App1(port 8443)
und App2(port 443)
. App1
verbindet sich mit App2
. Wenn App1
eine Verbindung zu App2
herstellt, wird der obige Fehler angezeigt. Ich weiß, dass dies ein sehr häufiger Fehler ist, und bin daher auf viele Lösungen in verschiedenen Foren und auf verschiedenen Websites gestoßen. Ich habe den folgenden Eintrag in server.xml
beider Kater:
keystoreFile="c:/.keystore"
keystorePass="changeit"
Auf jeder Site wird derselbe Grund angegeben, warum das von App2 angegebene Zertifikat nicht im vertrauenswürdigen Speicher von App1 JVM gespeichert ist. Dies scheint auch zuzutreffen, als ich im IE Browser versucht habe, auf dieselbe URL zuzugreifen. Dies funktioniert. Aber wenn die gleiche URL von Java Client (in meinem Fall) getroffen wird, erhalte ich den obigen Fehler. Um es in den Truststore zu legen, habe ich diese drei Optionen ausprobiert:
Option1
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Option2 Einstellung unten in Umgebungsvariable
CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Option3 Einstellung unten in Umgebungsvariable
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 vorgeschlagenen Java-Ansatzes. Wie man ungültige SSL-Zertifikate mit Apache behandelt HttpClient? von Pascal Thivent dh Ausführen des Programms InstallCert.
Aber dieser Ansatz ist in Ordnung für das Devbox-Setup, aber ich kann ihn nicht in der Produktionsumgebung verwenden.
Ich frage mich, warum drei Ansätze, die oben erwähnt wurden, nicht funktioniert haben, als ich die gleichen Werte in server.xml
von app2
Server und die gleichen Werte in Truststore durch Einstellung erwähnt habe
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
im app1
Programm.
Weitere Informationen dazu, wie ich die Verbindung herstelle:
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());
Sie müssen das Zertifikat für App2 zur Truststore-Datei der verwendeten JVM hinzufügen, die sich unter %Java_HOME%\lib\security\cacerts
befindet.
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 .
javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX-Pfadaufbau fehlgeschlagen: Sun.security.provider.certpath.SunCertPathBuilderException: Es wurde kein gültiger Zertifizierungspfad für das angeforderte Ziel gefunden
• Als ich die Fehlermeldung erhielt, habe ich versucht, die Bedeutung des Ausdrucks bei Google zu ermitteln, und festgestellt, dass dieses Problem auftritt, wenn ein Server sein HTTPS-SSL-Zertifikat ändert und unsere ältere Version von Java das nicht erkennt Stammzertifizierungsstelle (CA).
• 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-Zertifikatskette (im Internet Explorer gibt es ein Schlosssymbol). Klicken Sie auf das Schloss, um das Zertifikat anzuzeigen.
• Gehen Sie zu "Details" des Zertifikats und "In Datei kopieren". Kopieren Sie es im Format Base64 (.cer). Es wird auf Ihrem Desktop gespeichert.
• Installieren Sie das Zertifikat, indem Sie alle Warnungen ignorieren.
• Auf diese Weise habe ich die Zertifikatinformationen der URL erfasst, auf die ich zugreifen wollte.
Jetzt musste ich meine Java -Version erstellen, um über das Zertifikat Bescheid zu wissen, damit es die Erkennung der URL nicht verweigert. In diesem Zusammenhang muss ich erwähnen, dass ich gegoogelt habe, dass die Stammzertifikatsinformationen standardmäßig im Speicherort von JDK \ jre\lib\security gespeichert bleiben 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. Der Befehl Eingabeaufforderung wird geöffnet (möglicherweise müssen Sie ihn als Administrator öffnen).
• Wechseln Sie in Ihr Verzeichnis Java/jreX/bin
• Geben Sie Folgendes ein
keytool -list -keystore D:\Java\jdk1.5.0_12\jre\lib\security\cacerts
Es gibt die Liste der aktuellen Zertifikate an, 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
Schlüsselspeichertyp: jks
Keystore-Anbieter: Sun.
Ihr Keystore enthält 44 Einträge
verisignclass3g2ca, 26. März 2004, trustedCertEntry,
Zertifikat-Fingerabdruck (MD5): A2: 33: 9B: 4C: 74: 78: 73: D4: 6C: E7: C1: F3: 8D: CB: 5C: E9
entrustclientca, 9. Januar 2003, trustedCertEntry,
Zertifikat-Fingerabdruck (MD5): 0C: 41: 2F: 13: 5B: A0: 54: F5: 96: 66: 2D: 7E: CD: 0E: 03: F4
thawtepersonalbasicca, 13. Februar 1999, trustedCertEntry,
Zertifikat-Fingerabdruck (MD5): E6: 0B: D2: C9: CA: 2D: 88: DB: 1A: 71: 0E: 4B: 78: EB: 02: 41
addtrustclass1ca, 1. Mai 2006, trustedCertEntry,
Zertifikat-Fingerabdruck (MD5): 1E: 42: 95: 02: 33: 92: 6B: B9: 5F: C0: 7F: DA: D6: B2: 4B: FC
verisignclass2g3ca, 26. März 2004, trustedCertEntry,
Zertifikat-Fingerabdruck (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.
• Hierzu ist wie folgt vorzugehen:
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 in die Cacert-Datei eingefügt.
Es ist die Lösung, die ich für die oben erwähnte Ausnahme gefunden habe !!
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);
}
}
das hat mein Problem gelöst:
.crt
-Datei herunterecho -n | openssl s_client -connect <your domain>:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/<your domain>.crt
<your domain>
durch Ihre Domain (z. B. jossef.com
)..crt
in Javas Zertifikatspeicher cacerts
ankeytool -import -v -trustcacerts -alias <your domain> -file ~/<your domain>.crt -keystore <Java HOME>/jre/lib/security/cacerts -keypass changeit -storepass changeit
<your domain>
durch Ihre Domain (z. B. jossef.com
).<Java HOME>
durch Ihr Java AusgangsverzeichnisObwohl ich mein Zertifikat in den Standardzertifikatsspeichern von Java
installiert habe, Tomcat ignoriert dies (anscheinend ist es nicht für die Verwendung von Java-Standardzertifikatsspeichern konfiguriert).
Um dies zu hacken, fügen Sie Folgendes irgendwo in Ihren Code ein:
String certificatesTrustStorePath = "<Java HOME>/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
// ...
In meinem Fall bestand das Problem darin, dass der Webserver nur das Zertifikat und die Zwischenzertifizierungsstelle sendete, nicht die Stammzertifizierungsstelle. Durch Hinzufügen dieser JVM-Option wurde das Problem behoben: -Dcom.Sun.security.enableAIAcaIssuers=true
Die Zugriffsmethode caIssuers der Erweiterung Authority Information Access wird unterstützt. Es ist aus Kompatibilitätsgründen standardmäßig deaktiviert und kann aktiviert werden, indem die Systemeigenschaft
com.Sun.security.enableAIAcaIssuers
auf den Wert true gesetzt wird.Bei Festlegung auf "true" 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 ermitteln, sofern es sich um einen URI vom Typ "ldap", "http" oder "ftp" handelt.
Meine cacerts Akte war total leer. Ich habe dieses Problem gelöst, indem ich die cacerts-Datei von meinem Windows-Computer kopiert habe (das verwendet Oracle Java 7) und sie auf meine Linux-Box (OpenJDK) kopiert 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
Bisher hat es super geklappt.
Ein weiterer Grund könnte eine veraltete Version von JDK sein. Ich habe die jdk-Version 1.8.0_60 verwendet und durch einfaches Aktualisieren auf die neueste Version das Zertifikatproblem behoben.
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());
Mit Tomcat 7 unter Linux hat dies den Trick getan.
String certificatesTrustStorePath = "/etc/alternatives/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Unter Linux ist $Java_HOME
nicht immer eingerichtet, aber normalerweise /etc/alternatives/jre
zeigt auf $Java_HOME/jre
Für mich trat dieser Fehler auch auf, als ich versuchte, eine Verbindung zu einem Prozess hinter einem NGINX-Reverse-Proxy herzustellen, der das SSL handhabte.
Es stellte sich heraus, dass es sich bei dem Problem um ein Zertifikat handelte, bei dem nicht die gesamte Zertifikatskette verkettet war. Als ich Zwischenzertifikate hinzufügte, war das Problem gelöst.
Hoffe das hilft.
Ich habe jdk1.8.0_171
verwendet, als ich auf dasselbe Problem gestoßen bin. 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 1.8.0_181
aktualisiert und es hat wie ein Zauber funktioniert.
ich habe ein kleines Win32 (WinXP 32bit Testet) dummes Cmd (Kommandozeilen) Skript geschrieben, das nach allen Java Versionen in Programmdateien sucht und ihnen ein Zertifikat hinzufügt. Das Passwort muss die Standardeinstellung "changeit" sein oder es muss selbst im Skript geändert werden :-)
@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
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 uns ansehen: cd /usr/local/Java/jdk1.7.0_15/jre/lib/security
Die Standarddatei cacerts befindet sich hier. Fügen Sie das nicht vertrauenswürdige Zertifikat ein.
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 verwenden, Java1_8_x als JVM.
Für MacOS X unten ist der genaue Befehl, der für mich funktioniert hat, wo ich mit Doppelhypern in der Option 'importcert' versuchen musste, was funktioniert hat:
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
aus Sicherheitsgründen sollten wir in unserer Implementierung keine selbstsignierten Zertifikate verwenden. Wenn es jedoch um die Entwicklung geht, müssen wir häufig Testumgebungen verwenden, die selbst signierte Zertifikate haben. Ich habe versucht, dieses Problem programmgesteuert in meinem Code zu beheben, und es ist fehlgeschlagen. Durch das Hinzufügen des Zertifikats zum Trust-Store von jre wurde das Problem behoben. Finden sie unten schritte,
Laden Sie das Site-Zertifikat herunter.
Kopieren Sie das Zertifikat (zB cert_file.cer) in das Verzeichnis $ Java_HOME\Jre\Lib\Security
Öffnen Sie CMD in Administrator und ändern Sie das Verzeichnis in $ Java_HOME\Jre\Lib\Security
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 das Keytool nicht erkennbar ist, lesen Sie dies nach.
Geben Sie yes wie unten ein
Vertrauen Sie diesem Zertifikat: [Ja]
Update
Wenn Ihr App-Server JBoss ist, versuchen Sie, die folgende Systemeigenschaft hinzuzufügen
System.setProperty("org.jboss.security.ignoreHttpsHost","true");
Hoffe das hilft!
Ich stoße mit AndroidStudio
, Charles Proxy
, JUnit
und Robolectric
auf dieses Problem. Danke @SimonSez, ich konnte das Problem lösen.
Bitte beachten Sie: Da der Schlüsselpunkt in der Änderung von cacerts
liegt, kann dies zu Problemen führen (zB Aktualisierung der IDE ). Ich würde Ihnen empfehlen kopiere die ursprüngliche cacerts
Datei in ein separates Verzeichnis und bearbeite sie bei Bedarf.
%Java_HOME%
- Android verwendet ein anderes JavaHome. Den vollständigen Pfad finden Sie auf der Registerkarte UnitTests resulr
. In meinem Fall ist es /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home
Charles-Zertifikat herunterladen (z. B. Ordner Downloads
)
Führen Sie den Befehl aus
Sudo keytool -import -noprompt -trustcacerts -alias charles -file <path to Charles certificate.pem> -keystore "Java_HOME/jre/lib/security/cacerts" -storepass changeit
Zum Beispiel
Sudo keytool -import -noprompt -trustcacerts -alias charles -file ~/Downloads/charles-ssl-proxying-certificate.pem -keystore "/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/security/cacerts" -storepass changeit