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

Emmajiugo Punkte 195

Für OkHttpClient hat diese Lösung bei mir funktioniert. Es könnte jemandem helfen, der die Bibliothek verwendet...

try {

            String proxyHost = "proxy_host";
            String proxyUsername = "proxy_username";
            String proxyPassword = "proxy_password";

            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, "port goes here"));

            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                    @Override
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                    @Override
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient client = new OkHttpClient().newBuilder()
                    .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
                    .hostnameVerifier((hostname, session) -> true)
                    .connectTimeout(timeout, TimeUnit.SECONDS)
                    .proxy(proxy)
                    .proxyAuthenticator((route, response) -> {
                        String credential = Credentials.basic(proxyUsername, proxyPassword);
                        return response.request().newBuilder()
                                .header("Proxy-Authorization", credential)
                                .build();
                    })
                    .build();

            MediaType mediaType = MediaType.parse("application/json");
            RequestBody requestBody = RequestBody.create(payload, mediaType);

            Request request = new Request.Builder()
                    .url(url)
                    .header("Authorization", "authorization data goes here")
                    .method(requestMethod, requestBody)
                    .build();

            Response response = client.newCall(request).execute();

            resBody = response.body().string();

            int responseCode = response.code();

        } catch (Exception ex) {
        }

-1voto

oraclesoon Punkte 769

Wenn Tomcat auf einem Ubuntu-Server läuft, können Sie mit dem Befehl "ps -ef | grep tomcat" herausfinden, welches Java verwendet wird:

Beispiel:

/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 damit befassen: cd /usr/local/java/jdk1.7.0_15/jre/lib/security

Standard cacerts Datei befindet sich hier. Fügen Sie das nicht vertrauenswürdige Zertifikat in diese Datei ein.

-3voto

Notfalls können Sie SSL auch ganz oder pro Verbindung deaktivieren (dies wird für die Produktion nicht empfohlen!), siehe https://stackoverflow.com/a/19542614/32453

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