Beim Versuch, eine Anfrage an einen http-Server zu senden, wurde die folgende Ausnahme angezeigt:
Hier ist der Code, den ich verwendet habe
URL url = new URL(
"https://www.abc.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
// wr.writeBytes(params);
wr.flush();
wr.close();
BufferedReader br = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
Hier ist die Ausnahme:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
at com.amazon.mzang.tools.httpchecker.CategoryYank.getPV(CategoryYank.java:32)
at com.amazon.mzang.tools.httpchecker.CategoryYank.main(CategoryYank.java:18)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
... 13 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 19 more
Der Server gehört mir nicht. Gibt es eine Möglichkeit, diese Ausnahme zu ignorieren?
java
ssl
certificate
ssl-certificate
DeepNightTwo
quelle
quelle
Antworten:
Wenn Sie das Zertifikat insgesamt ignorieren möchten, sehen Sie sich die Antwort hier an: Ignorieren Sie das selbstsignierte SSL-Zertifikat mit Jersey Client
Dies macht Ihre App jedoch anfällig für Man-in-the-Middle-Angriffe.
Oder versuchen Sie, das Zertifikat als vertrauenswürdiges Zertifikat zu Ihrem Java-Speicher hinzuzufügen. Diese Seite kann hilfreich sein. http://blog.icodejava.com/tag/get-public-key-of-ssl-certificate-in-java/
Hier ist ein weiterer Thread, der zeigt, wie Sie Ihrem Geschäft ein Zertifikat hinzufügen. Java SSL-Verbindung, Serverzertifikat programmgesteuert zum Keystore hinzufügen
Der Schlüssel ist:
KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(someCert); ks.setEntry("someAlias", newEntry, null);
quelle
Ich habe den folgenden Code verwendet, um die SSL-Prüfung in meinem Projekt zu überschreiben, und es hat bei mir funktioniert.
package com.beingjavaguys.testftp; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.net.URLConnection; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate; /** * Fix for Exception in thread "main" javax.net.ssl.SSLHandshakeException: * sun.security.validator.ValidatorException: PKIX path building failed: * sun.security.provider.certpath.SunCertPathBuilderException: unable to find * valid certification path to requested target */ public class ConnectToHttpsUrl { public static void main(String[] args) throws Exception { /* Start of Fix */ TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // Create all-trusting host name verifier HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; // Install the all-trusting host verifier HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); /* End of the fix*/ URL url = new URL("https://nameofthesecuredurl.com"); URLConnection con = url.openConnection(); Reader reader = new InputStreamReader(con.getInputStream()); while (true) { int ch = reader.read(); if (ch == -1) break; System.out.print((char) ch); } } }
quelle
sc.init()
kann das dritte Argument seinnull
. (Ein Standardwert wird angegeben.)Setzen Sie die
validateTLSCertificates
Eigenschaftfalse
für Ihren JSoup- Befehl auf.Jsoup.connect("https://google.com/").validateTLSCertificates(false).get();
quelle
FWIW, unter Ubuntu 10.04.2 LTS hat die Installation der Pakete ca-certificates-java und ca-certificates dieses Problem für mich behoben.
quelle
Ich habe den gleichen Fehler beim Ausführen des folgenden einfachen Spring-Boot + RestAssured-Tests erhalten.
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static com.jayway.restassured.RestAssured.when; import static org.apache.http.HttpStatus.SC_OK; @RunWith(SpringJUnit4ClassRunner.class) public class GeneratorTest { @Test public void generatorEndPoint() { when().get("https://bal-bla-bla-bla.com/generators") .then().statusCode(SC_OK); } }
Die einfache Lösung in meinem Fall ist das Hinzufügen von 'useRelaxedHTTPSValidations ()'.
Dann sieht der Test so aus
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static com.jayway.restassured.RestAssured.when; import static org.apache.http.HttpStatus.SC_OK; @RunWith(SpringJUnit4ClassRunner.class) public class GeneratorTest { @Before public void setUp() { RestAssured.useRelaxedHTTPSValidation(); } @Test public void generatorEndPoint() { when().get("https://bal-bla-bla-bla.com/generators") .then().statusCode(SC_OK); } }
quelle
Wenn es sich um ein fehlendes Zwischenzertifikat handelt, können Sie Oracle JRE aktivieren, um das fehlende Zwischenzertifikat automatisch herunterzuladen, wie in dieser Antwort erläutert .
Legen Sie einfach die Java-Systemeigenschaft fest
-Dcom.sun.security.enableAIAcaIssuers=true
Damit dies funktioniert, muss das Serverzertifikat den URI für das Zwischenzertifikat (den Aussteller des Zertifikats) bereitstellen. Soweit ich das beurteilen kann, tun dies auch Browser und sollten genauso sicher sein - ich bin jedoch kein Sicherheitsexperte.
Bearbeiten: Wenn ich mich richtig erinnere, scheint dies zumindest mit Java 8 zu funktionieren und ist hier für Java 9 dokumentiert .
quelle
Wenn Sie CloudFoundry verwenden, müssen Sie das JAR explizit zusammen mit dem Keystore mit dem Zertifikat verschieben.
quelle
Ich habe mich auch diesem Problem gestellt. Ich hatte
JDK 1.8.0_121
. Ich habe JDK auf aktualisiert1.8.0_181
und es hat wie ein Zauber funktioniert.quelle