386 Stimmen

Java: sun.security.provider.certpath.SunCertPathBuilderException: es konnte kein gültiger Zertifikatspfad zum angeforderten Ziel gefunden werden

Ich habe eine Klasse, die eine Datei von einem https Server herunterlädt. Wenn ich es ausführe, werden viele Fehler zurückgegeben. Es scheint, dass ich ein Problem mit meinem Zertifikat habe. Ist es möglich, die Client-Server-Authentifizierung zu ignorieren? Wenn ja, wie?

package com.da;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;

import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncGet;
import org.apache.http.nio.client.methods.HttpAsyncPost;

public class RSDDownloadFile {
    static FileOutputStream fos;

    public void DownloadFile(String URI, String Request) throws Exception
    {
        java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",
                "Lang=EN&AuthToken=package", null);
        System.out.println("URI-Abfrage: " + uri.toString());

        HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
        httpclient.start();
        try {
            Future future = httpclient.execute(
                    new HttpAsyncGet(uri),
                    new ResponseCallback(), null);

            Boolean result = future.get();
            if (result != null && result.booleanValue()) {
                System.out.println("\nAnforderung erfolgreich ausgeführt");
            } else {
                System.out.println("Anforderung fehlgeschlagen");
            }              
        } 
        catch(Exception e){
            System.out.println("[DownloadFile] Ausnahme: " + e.getMessage());
        }
        finally {
            System.out.println("Herunterfahren");
            httpclient.shutdown();
        }
        System.out.println("Fertig");  

    }

    static class ResponseCallback extends AsyncCharConsumer {

        @Override
        protected void onResponseReceived(final HttpResponse response) {
             System.out.println("Antwort: " + response.getStatusLine());
             System.out.println("Header: " + response.toString());
             try {   
                 //if(response.getStatusLine().getStatusCode()==200)
                     fos = new FileOutputStream( "Response.html" );
             }catch(Exception e){
                 System.out.println("[onResponseReceived] Ausnahme: " + e.getMessage());
             }
        }

        @Override
        protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
            try
            {
                while (buf.hasRemaining()) 
                {
                    //System.out.print(buf.get());
                    fos.write(buf.get());
                }
            }catch(Exception e)
            {
                System.out.println("[onCharReceived] Ausnahme: " + e.getMessage());
            }
        }

        @Override
        protected void onCleanup() {
            try
            {             
                if(fos!=null)
                    fos.close();
            }catch(Exception e){
                System.out.println("[onCleanup] Ausnahme: " + e.getMessage());         
            }
             System.out.println("onCleanup()");
        }

        @Override
        protected Boolean buildResult() {
            return Boolean.TRUE;
        }

    }
}

Fehler:

URI-Abfrage: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package
Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception
SEVERE: I/O-Fehler: Allgemeines SSLEngine-Problem
javax.net.ssl.SSLHandshakeException: Allgemeines SSLEngine-Problem
    at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)
    at javax.net.ssl.SSLEngine.wrap(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)
    at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)
    at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
    at java.lang.Thread.run(Unknown Source)
Verursacht durch: javax.net.ssl.SSLHandshakeException: Allgemeines SSLEngine-Problem
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)
    ... 9 more
Verursacht durch: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 21 more
onCleanup()

[DownloadFile] Ausnahme: javax.net.ssl.SSLHandshakeException: Allgemeines SSLEngine-Problem
Herunterfahren
Fertig

5 Stimmen

Einmal habe ich diesen Fehler bekommen und unser Sicherheitsteam kontaktiert, und es stellte sich heraus, dass ich das JAR patchen musste, das wir verwendet haben, da unser Team ein veraltetes von der Firma bereitgestelltes benutzte. Nur als Information für alle anderen, die sich in einer ähnlichen Situation befinden könnten.

0 Stimmen

Ich habe dieses PKIX-Problem in zwei Fällen erhalten, beim Herunterladen der Maven-Abhängigkeit direkt aus dem Internet anstelle des Caches meiner Organisation. Dies wurde durch die Korrektur der setting.xml-Datei behoben. Das zweite Mal hatte ich dieses Problem, als ich versuchte, auf Microsoft URI für oAuth-Token zuzugreifen. Dies wurde durch Hinzufügen der cacert-Datei in meinen JDK-Pfad behoben.

6voto

vallismortis Punkte 6584

Die Quelle dieses Fehlers in meiner Apache 2.4-Instanz (bei Verwendung eines Comodo-Wildcard-Zertifikats) war ein unvollständiger Pfad zum mit SHA-1 signierten Stammzertifikat. Im ausgestellten Zertifikat gab es mehrere Ketten, und die Kette, die zu einem SHA-1-Stammzertifikat führte, enthielt kein Zwischenzertifikat. Moderne Browser wissen, wie sie damit umgehen sollen, aber Java 7 behandelt dies standardmäßig nicht (obwohl es einige umständliche Möglichkeiten gibt, dies im Code zu erreichen). Das Ergebnis sind Fehlermeldungen, die identisch aussehen wie bei selbstsignierten Zertifikaten:

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:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 22 more

In diesem Fall wird die Meldung "unable to find valid certification path to requested target" aufgrund des fehlenden Zwischenzertifikats generiert. Sie können über den SSL Labs-Test gegen den Server überprüfen, welches Zertifikat fehlt. Sobald Sie das entsprechende Zertifikat gefunden haben, laden Sie es herunter und fügen Sie es (falls der Server unter Ihrer Kontrolle steht) dem Zertifikatspaket hinzu. Alternativ können Sie das fehlende Zertifikat lokal importieren. Das Beheben dieses Problems auf dem Server ist eine allgemeinere Lösung für das Problem.

0 Stimmen

ssllabs.com/ssltest ist ein Retter, man muss es nur mit einer gültigen Zertifikatsvalidierung vergleichen.

5voto

Lalaphoon Punkte 189

Hatte das Problem wie dieses Bild.

Bildbeschreibung hier eingeben

Habe ein paar Lösungen ausprobiert. Aber festgestellt, dass selbst wenn es sich um dasselbe Projekt handelt, es an einem anderen Arbeitsplatz einwandfrei funktioniert. Keine zusätzlichen Einstellungen erforderlich. Daher vermuteten wir, dass es sich um ein Umgebungsproblem handelt. Wir haben versucht, die JDK-Version und die IDE zu ändern, aber es hat nicht funktioniert. Es dauerte etwa 4 Stunden, bis wir die bestbewertete Antwort ausprobierten. Ich habe den in dieser Antwort erwähnten Fehler nicht gefunden, aber über meinen Browser habe ich herausgefunden, dass es eine Zertifizierung von Charles für die HTTP-URL (Schloss) gab. Dann habe ich realisiert, dass mein Charles die ganze Zeit aktiv war. Sobald ich das ausgeschaltet habe, hat alles einwandfrei funktioniert.

Also habe ich meine Erfahrung hinterlassen, die für deinen Fall hilfreich sein könnte.

5voto

Daniel De León Punkte 12365

Es gibt viele Möglichkeiten, das zu lösen...

Ein Weg besteht darin, die TrustStore-Zertifikate in einer Keystore-Datei festzulegen und sie im Anwendungspfad abzulegen. Legen Sie diese Systemeigenschaften in der main-Methode fest:

public static void main(String[] args) {
  System.setProperty("javax.net.ssl.trustStore", "trust-store.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "TrustStore");
  ...
}

Ein anderer Weg besteht darin, den Keystore als Ressourcendatei in das Projekt-Jar-Datei zu platzieren und ihn zu laden:

public static SSLContext createSSLContext(String resourcePath, String pass) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException {
  // Keystore initialisieren
  final char[] password = pass.toCharArray();
  KeyStore ks = KeyStore.getInstance("JKS");
  ks.load(ThisClass.class.getResourceAsStream(resourcePath
  ), password);

  // Key Manager Factory einrichten.
  KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
  kmf.init(ks, password);

  // Trust Manager Factory einrichten.
  TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
  tmf.init(ks);

  SSLContext sslc = SSLContext.getInstance("TLS");
  sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
  return sslc;
}

public static void main(String[] args) {
  SSLContext.setDefault(
    createSSLContext("/trust-store.jks", "TrustStore"));
  ...
}

In Windows können Sie auch diese Lösung ausprobieren: https://stackoverflow.com/a/59056537/980442


Ich habe die Keystore-Datei aus einer Zertifizierungsstelle-CA .crt-Datei auf diese Weise erstellt:

keytool -import -alias ca -keystore trust-store.jks -storepass TrustStore -trustcacerts -file ca.crt

Zu Ihrer Information: https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslclient.html

4voto

gavenkoa Punkte 40749

Für diejenigen, die Debian und vorkonfiguriertes Java mögen:

sudo mkdir /usr/share/ca-certificates/test/  # mischen Sie nicht mit anderen Zertifikaten
sudo cp ~/tmp/test.loc.crt /usr/share/ca-certificates/test/
sudo dpkg-reconfigure --force ca-certificates  # überprüfen Sie Ihr Zertifikat im curses GUI!
sudo update-ca-certificates --fresh --verbose

Vergessen Sie nicht, /etc/default/cacerts zu überprüfen:

# Aktivierung/Deaktivierung von Updates des Keystores /etc/ssl/certs/java/cacerts
cacerts_updates=yes

Um ein Zertifikat zu entfernen:

sudo rm /usr/share/ca-certificates/test/test.loc.crt
sudo rm /etc/ssl/certs/java/cacerts
sudo update-ca-certificates --fresh --verbose

3voto

Radu Toader Punkte 1411

Ich hatte das gleiche Problem mit dem Zertifikatsfehler und es lag am SNI: Der HTTP-Client, den ich verwendet habe, hatte SNI nicht implementiert. Ein Versionsupdate hat also geholfen

        org.apache.httpcomponents
        httpclient
        4.3.6

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