Es konnte kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden werden – Fehler auch nach dem Import des Zertifikats
Lesezeit: 14 Minuten
DerCoder
Ich habe einen Java-Client, der versucht, mit einem selbstsignierten Zertifikat auf einen Server zuzugreifen.
Wenn ich versuche, auf dem Server zu posten, erhalte ich die folgende Fehlermeldung:
Es konnte kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden werden
Nachdem ich einige Recherchen zu diesem Thema angestellt hatte, habe ich dann Folgendes getan.
Der Domänenname meines Servers wurde als root.cer Datei.
In der JRE meines Glassfish-Servers habe ich Folgendes ausgeführt: keytool -import -alias example -keystore cacerts -file root.cer
Um zu überprüfen, ob das Zertifikat erfolgreich zu meinem Cacert hinzugefügt wurde, habe ich Folgendes getan: keytool -list -v -keystore cacerts
Ich kann sehen, dass das Zertifikat vorhanden ist.
Dann habe ich Glassfish neu gestartet und den “Post” zurückgezogen.
Ich bekomme immer noch den gleichen Fehler.
Ich habe das Gefühl, dass dies daran liegt, dass mein Glassfish nicht die von mir geänderte Cacert-Datei liest, sondern möglicherweise eine andere.
Hatte jemand von euch dieses Problem und kann mich in die richtige Richtung schubsen?
Nur um zu verdeutlichen: “Ich habe einen Java-Client, der versucht, mit einem selbstsignierten Zertifikat auf einen Server zuzugreifen.”: Sie sprechen von der Verwendung von Client-Zertifikaten, die selbstsigniert sind, nicht wahr? Gibt es eine spezifische Konfiguration für Ihre Connector-Einstellungen auf Glassfish (insbesondere Trust Store-Einstellungen)?
– Bruno
9. Februar 2012 um 12:25 Uhr
“Ich habe einen Java-Client, der versucht, mit einem selbstsignierten Zertifikat auf einen Server zuzugreifen.”: Sie sprechen von der Verwendung von Client-Zertifikaten, die selbstsigniert sind, nicht wahr? – Jawohl.
– Der Coder
9. Februar 2012 um 13:51 Uhr
Ich habe 2 Einstellungen in Glassfish JVM gefunden: -Djavax.net.ssl.keyStore=${com.sun.aas.instanceRoot}/config/keystore.jks und -Djavax.net.ssl.trustStore=${com.sun. aas.instanceRoot}/config/cacerts.jks. Ich muss jetzt per Zertifikat zu einem von denen hinzufügen. Können Sie bestätigen, dass es der Keystore ist, dem ich es hinzufüge?
– Der Coder
9. Februar 2012 um 13:52 Uhr
Auf dem Server ist der Schlüsselspeicher für das Serverzertifikat und seinen privaten Schlüssel (der Schlüsselspeicher ist für das, was der lokalen Partei „gehört“). Der Truststore ist für die Zertifikate, die verwendet werden, um das Vertrauen in die Remote-Partei zu überprüfen. Sie sollten das Clientzertifikat zu Ihrem Server-Truststore hinzufügen. (Sehen Sie sich dies auch an, obwohl Glassfish anscheinend nicht den Standardspeicherort der JRE verwendet.)
– Bruno
9. Februar 2012 um 13:56 Uhr
Sie können alle SSL-Zertifikate blind akzeptieren, wie in diesem vollständig ausführbaren Beispielcode gezeigt – Das ist natürlich unsicher!: nakov.com/blog/2009/07/16/…
– Dreamspace-Präsident
19. Juni 2018 um 13:14 Uhr
Dirk-Willem van Gulik
Leider – es könnte vieles sein – und viele App-Server und andere Java-„Wrapper“ neigen dazu, mit Eigenschaften und ihrer „eigenen“ Version von Schlüsselbunden und so weiter zu spielen. Es kann sich also um etwas ganz anderes handeln.
um zu sehen, ob das hilft. Anstelle von ‘alle’ kann man auch ‘ssl’, Schlüsselmanager und Vertrauensmanager einstellen – was in Ihrem Fall helfen kann. Wenn Sie es auf “Hilfe” setzen, wird auf den meisten Plattformen etwas wie unten aufgeführt.
Unabhängig davon – stellen Sie sicher, dass Sie den Unterschied zwischen dem Schlüsselspeicher (in dem Sie den privaten Schlüssel und das Zertifikat haben, mit dem Sie Ihre eigene Identität beweisen) und dem Vertrauensspeicher (der bestimmt, wem Sie vertrauen) vollständig verstehen – und die Tatsache, dass auch Ihre eigene Identität hat eine ‘Vertrauenskette’ zur Wurzel – die von jeder Kette zu einer Wurzel getrennt ist, die Sie brauchen, um herauszufinden, ‘wem’ Sie vertrauen.
all turn on all debugging
ssl turn on ssl debugging
The following can be used with ssl:
record enable per-record tracing
handshake print each handshake message
keygen print key generation data
session print session activity
defaultctx print default SSL initialization
sslctx print SSLContext tracing
sessioncache print session cache tracing
keymanager print key manager tracing
trustmanager print trust manager tracing
pluggability print pluggability tracing
handshake debugging can be widened with:
data hex dump of each handshake message
verbose verbose handshake message printing
record debugging can be widened with:
plaintext hex dump of record plaintext
packet print raw SSL/TLS packets
Vielen Dank! -Djavax.net.ssl.trustStore=/location_of/trustStore hat mein Problem gelöst und die Debug-Informationen waren auch sehr hilfreich.
– RH
19. Juli 2016 um 23:30 Uhr
java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=trustStore … gibt den folgenden Fehler aus: Fehler: Hauptklasse konnte nicht gefunden oder geladen werden …
– rohith
9. April 2019 um 10:12 Uhr
Natürlich müssen Sie möglicherweise auch das Passwort des Truststores mit -Djavax.net.ssl.trustStorePassword=changeit angeben
– Benutzer1754036
6. Februar 2020 um 22:52 Uhr
Benutzer6258309
Hier ist die Lösung, folgen Sie dem untenstehenden Link Schritt für Schritt:
/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import java.net.URL;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
public class InstallCert {
public static void main(String[] args) throws Exception {
String host;
int port;
char[] passphrase;
if ((args.length == 1) || (args.length == 2)) {
String[] c = args[0].split(":");
host = c[0];
port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
String p = (args.length == 1) ? "changeit" : args[1];
passphrase = p.toCharArray();
} else {
System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
return;
}
File file = new File("jssecacerts");
if (file.isFile() == false) {
char SEP = File.separatorChar;
File dir = new File(System.getProperty("java.home") + SEP
+ "lib" + SEP + "security");
file = new File(dir, "jssecacerts");
if (file.isFile() == false) {
file = new File(dir, "cacerts");
}
}
System.out.println("Loading KeyStore " + file + "...");
InputStream in = new FileInputStream(file);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(in, passphrase);
in.close();
SSLContext context = SSLContext.getInstance("TLS");
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
context.init(null, new TrustManager[] {tm}, null);
SSLSocketFactory factory = context.getSocketFactory();
System.out.println("Opening connection to " + host + ":" + port + "...");
SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
socket.setSoTimeout(10000);
try {
System.out.println("Starting SSL handshake...");
socket.startHandshake();
socket.close();
System.out.println();
System.out.println("No errors, certificate is already trusted");
} catch (SSLException e) {
System.out.println();
e.printStackTrace(System.out);
}
X509Certificate[] chain = tm.chain;
if (chain == null) {
System.out.println("Could not obtain server certificate chain");
return;
}
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
System.out.println();
System.out.println("Server sent " + chain.length + " certificate(s):");
System.out.println();
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
MessageDigest md5 = MessageDigest.getInstance("MD5");
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
System.out.println
(" " + (i + 1) + " Subject " + cert.getSubjectDN());
System.out.println(" Issuer " + cert.getIssuerDN());
sha1.update(cert.getEncoded());
System.out.println(" sha1 " + toHexString(sha1.digest()));
md5.update(cert.getEncoded());
System.out.println(" md5 " + toHexString(md5.digest()));
System.out.println();
}
System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
String line = reader.readLine().trim();
int k;
try {
k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
} catch (NumberFormatException e) {
System.out.println("KeyStore not changed");
return;
}
X509Certificate cert = chain[k];
String alias = host + "-" + (k + 1);
ks.setCertificateEntry(alias, cert);
OutputStream out = new FileOutputStream("jssecacerts");
ks.store(out, passphrase);
out.close();
System.out.println();
System.out.println(cert);
System.out.println();
System.out.println
("Added certificate to keystore 'jssecacerts' using alias '"
+ alias + "'");
}
private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
private static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 3);
for (int b : bytes) {
b &= 0xff;
sb.append(HEXDIGITS[b >> 4]);
sb.append(HEXDIGITS[b & 15]);
sb.append(' ');
}
return sb.toString();
}
private static class SavingTrustManager implements X509TrustManager {
private final X509TrustManager tm;
private X509Certificate[] chain;
SavingTrustManager(X509TrustManager tm) {
this.tm = tm;
}
public X509Certificate[] getAcceptedIssuers() {
throw new UnsupportedOperationException();
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
throw new UnsupportedOperationException();
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
this.chain = chain;
tm.checkServerTrusted(chain, authType);
}
}
}
Diese Lösung hat bei mir funktioniert, erfordert jedoch eine kleine Änderung in der privaten Klasse SavingTrustManager: public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0];}
– Richard
4. Juli 2016 um 20:29 Uhr
@Richard,@Paul,@user6258309 Ich habe den Fehler Exception in Thread „main“ java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(Unknown Source ) Wie kann ich das beheben
– Renjith Krishnan
27. Februar 2017 um 5:50 Uhr
Diese „Lösung“ ist radikal unsicher. Verwende nicht.
– Benutzer207421
6. Dezember 2018 um 10:26 Uhr
Diese Antwort ist hauptsächlich Code. Es erklärt nicht, warum oder warum es nicht funktioniert.
– Benutzer6490459
16. Dezember 2018 um 11:01 Uhr
Vic
Sie müssen die JSSE-Systemeigenschaften konfigurieren und insbesondere auf den Client-Zertifikatsspeicher verweisen.
Weitere Informationen finden Sie unter Details RedHat-Site.
Hatte das gleiche Problem mit Spring Boot, Spring Cloud-Microservices und einem selbstsignierten SSL-Zertifikat. Ich konnte keyStore und keyStorePassword in application.properties festlegen und es sofort zum Laufen bringen, aber es gelang mir nicht, dasselbe mit trustStore und trustStorePassword zu tun. Diese Antwort hat bei mir für den Trust Store funktioniert.
– Mate Simović
30. Juni 2017 um 14:42 Uhr
Алексей Присяжный
(Repost von meiner anderen Antwort)
Verwenden Sie das CLI-Dienstprogramm Schlüsselwerkzeug aus der Java-Softwareverteilung zum Importieren (und Vertrauen!) benötigte Zertifikate
Probe:
Wechseln Sie von cli in jre\bin
Schlüsselspeicher überprüfen (Datei im Verzeichnis jre\bin gefunden)
keytool -list -keystore ..\lib\security\cacerts
Passwort ist ändern Sie es
Laden Sie alle Zertifikate in Kette vom benötigten Server herunter und speichern Sie sie.
Fügen Sie Zertifikate hinzu (bevor Sie das Attribut „Schreibgeschützt“ in der Datei entfernen müssen ..\lib\security\cacerts), Lauf:
Ich hatte das gleiche Problem mit sbt.
Es wurde versucht, Abhängigkeiten von abzurufen repo1.maven.org über SSL
sagte aber, es sei “nicht in der Lage, einen gültigen Zertifizierungspfad zur angeforderten Ziel-URL zu finden”.
also folgte ich dieser Beitrag
und konnte immer noch keine Verbindung überprüfen.
Also habe ich darüber gelesen und festgestellt, dass das Root-Zertifikat nicht ausreicht, wie in der Post vorgeschlagen, also – Was bei mir funktioniert hat, war das Importieren der CA-Zwischenzertifikate in den Schlüsselspeicher.
Ich habe tatsächlich alle Zertifikate in der Kette hinzugefügt und es hat wie ein Zauber funktioniert.
Habe das gleiche erlebt: nur root importieren funktioniert nicht. Beim Importieren des Zwischenprodukts ist dies der Fall. Was könnte der Grund dafür sein?
root@c339504909345:/opt/jdk-minimal/jre/lib/security # keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 80 entries
JDK8
root@c39596768075:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts # keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 151 entries
Schritte zur Behebung
Ich habe das JDK 10-Zertifikat gelöscht und durch das JDK 8 ersetzt
Da ich Docker-Images baue, könnte ich das schnell mit mehrstufigen Builds tun
Ich baue eine minimale JRE mit jlink als /opt/jdk/bin/jlink \
--module-path /opt/jdk/jmods...
Also, hier sind die verschiedenen Pfade und die Reihenfolge der Befehle …
# Java 8
COPY --from=marcellodesales-springboot-builder-jdk8 /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts /etc/ssl/certs/java/cacerts
# Java 10
RUN rm -f /opt/jdk-minimal/jre/lib/security/cacerts
RUN ln -s /etc/ssl/certs/java/cacerts /opt/jdk-minimal/jre/lib/security/cacerts
Habe das gleiche erlebt: nur root importieren funktioniert nicht. Beim Importieren des Zwischenprodukts ist dies der Fall. Was könnte der Grund dafür sein?
– Wankog
1. Oktober 2020 um 6:22 Uhr
Ich arbeite an einem Tutorial für REST-Webdienste auf www.udemy.com (REST Java Web Services). Das Beispiel im Tutorial besagte, dass wir für SSL einen Ordner namens „trust_store“ in meinem Eclipse-„Client“-Projekt haben müssen, der eine „Schlüsselspeicher“-Datei enthalten sollte (wir hatten ein „Client“-Projekt, um den Dienst aufzurufen , und “service”-Projekt, das den REST-Webdienst enthielt – 2 Projekte im selben Eclipse-Arbeitsbereich, eines der Client, das andere der Dienst). Um die Dinge einfach zu halten, sagten sie, sie sollten “keystore.jks” vom Glassfish-App-Server (glassfish\domains\domain1\config\keystore.jks), den wir verwenden, kopieren und in diesen “trust_store”-Ordner legen, den sie mich erstellen ließen das Kundenprojekt. Das scheint sinnvoll zu sein: Die selbstsignierten Zertifikate im key_store des Servers würden den Zertifikaten im trust_store des Clients entsprechen. Als ich dies tat, bekam ich den Fehler, den der ursprüngliche Beitrag erwähnt. Ich habe dies gegoogelt und gelesen, dass der Fehler auf die Datei “keystore.jks” auf dem Client zurückzuführen ist, die kein vertrauenswürdiges/signiertes Zertifikat enthält, dass das gefundene Zertifikat selbstsigniert ist.
Um die Dinge klar zu halten, lassen Sie mich sagen, dass nach meinem Verständnis die Datei „keystore.jks“ selbstsignierte Zertifikate enthält und die Datei „cacerts.jks“ CA-Zertifikate enthält (von der CA signiert). „keystore.jks“ ist der „Schlüsselspeicher“ und „cacerts.jks“ ist der „Vertrauensspeicher“. Wie “Bruno”, ein Kommentator, oben sagt, ist “keystore.jks” lokal und “cacerts.jks” ist für Remote-Clients.
Also sagte ich mir, hey, glassfish hat auch die Datei „cacerts.jks“, die trust_store-Datei von glassfish. cacerts.jsk soll CA-Zertifikate enthalten. Und anscheinend muss mein Ordner trust_store eine Schlüsselspeicherdatei enthalten, die mindestens ein CA-Zertifikat enthält. Also habe ich versucht, die Datei „cacerts.jks“ in den von mir erstellten Ordner „trust_store“ in meinem Clientprojekt zu legen und die VM-Eigenschaften so zu ändern, dass sie auf „cacerts.jks“ statt auf „keystore.jks“ zeigen. Damit war der Fehler weg. Ich denke, alles, was es brauchte, war ein CA-Zertifikat, um zu funktionieren.
Dies ist möglicherweise nicht ideal für die Produktion oder sogar für die Entwicklung, die darüber hinausgeht, etwas zum Laufen zu bringen. Beispielsweise könnten Sie wahrscheinlich den Befehl „keytool“ verwenden, um CA-Zertifikate zur Datei „keystore.jks“ im Client hinzuzufügen. Aber hoffentlich grenzt dies zumindest die möglichen Szenarien ein, die hier vor sich gehen könnten, um den Fehler zu verursachen.
AUCH: Mein Ansatz schien für den Client nützlich zu sein (Serverzertifikat zu Client Trust_store hinzugefügt), es sieht so aus, als ob die obigen Kommentare zur Auflösung des ursprünglichen Beitrags für den Server nützlich sind (Clientzertifikat zu Server Trust_store hinzugefügt). Prost.
Einrichtung des Eclipse-Projekts:
MeinClientProjekt
Quelle
Prüfung
JRE-Systembibliothek
…
Vertrauensspeicher
—cacerts.jks —keystore.jks
Ausschnitt aus der Datei MyClientProject.java:
static {
// Setup the trustStore location and password
System.setProperty("javax.net.ssl.trustStore","trust_store/cacerts.jks");
// comment out below line
System.setProperty("javax.net.ssl.trustStore","trust_store/keystore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
//System.setProperty("javax.net.debug", "all");
// for localhost testing only
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return hostname.equals("localhost");
}
});
}
9156700cookie-checkEs konnte kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden werden – Fehler auch nach dem Import des Zertifikatsyes
Nur um zu verdeutlichen: “Ich habe einen Java-Client, der versucht, mit einem selbstsignierten Zertifikat auf einen Server zuzugreifen.”: Sie sprechen von der Verwendung von Client-Zertifikaten, die selbstsigniert sind, nicht wahr? Gibt es eine spezifische Konfiguration für Ihre Connector-Einstellungen auf Glassfish (insbesondere Trust Store-Einstellungen)?
– Bruno
9. Februar 2012 um 12:25 Uhr
“Ich habe einen Java-Client, der versucht, mit einem selbstsignierten Zertifikat auf einen Server zuzugreifen.”: Sie sprechen von der Verwendung von Client-Zertifikaten, die selbstsigniert sind, nicht wahr? – Jawohl.
– Der Coder
9. Februar 2012 um 13:51 Uhr
Ich habe 2 Einstellungen in Glassfish JVM gefunden: -Djavax.net.ssl.keyStore=${com.sun.aas.instanceRoot}/config/keystore.jks und -Djavax.net.ssl.trustStore=${com.sun. aas.instanceRoot}/config/cacerts.jks. Ich muss jetzt per Zertifikat zu einem von denen hinzufügen. Können Sie bestätigen, dass es der Keystore ist, dem ich es hinzufüge?
– Der Coder
9. Februar 2012 um 13:52 Uhr
Auf dem Server ist der Schlüsselspeicher für das Serverzertifikat und seinen privaten Schlüssel (der Schlüsselspeicher ist für das, was der lokalen Partei „gehört“). Der Truststore ist für die Zertifikate, die verwendet werden, um das Vertrauen in die Remote-Partei zu überprüfen. Sie sollten das Clientzertifikat zu Ihrem Server-Truststore hinzufügen. (Sehen Sie sich dies auch an, obwohl Glassfish anscheinend nicht den Standardspeicherort der JRE verwendet.)
– Bruno
9. Februar 2012 um 13:56 Uhr
Sie können alle SSL-Zertifikate blind akzeptieren, wie in diesem vollständig ausführbaren Beispielcode gezeigt – Das ist natürlich unsicher!: nakov.com/blog/2009/07/16/…
– Dreamspace-Präsident
19. Juni 2018 um 13:14 Uhr