it-swarm.com.de

Wie zu beheben javax.net.ssl.SSLHandshakeException Fehler?

Ich habe mich mit VPN verbunden, um die Inventar-API einzurichten, um die Produktliste abzurufen, und es funktioniert gut. Sobald ich das Ergebnis vom Webservice erhalten habe, binde ich mich an die Benutzeroberfläche. Und ich habe auch Paypal in meine Anwendung für die Express-Kaufabwicklung integriert, wenn ich einen Zahlungsaufruf mache. Ich sehe diesen Fehler. Ich benutze Servlet für den Back-End-Prozess. Kann jemand sagen, wie man dieses Problem beheben kann?

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
83
selladurai

Zunächst müssen Sie das öffentliche Zertifikat von dem Server erhalten, zu dem Sie eine Verbindung herstellen möchten. Dies kann auf verschiedene Weisen geschehen, z. B. indem Sie den Serveradministrator kontaktieren und danach fragen, mithilfe von OpenSSL den Download durchführen , oder, da dies wie ein HTTP-Server zu sein scheint, eine Verbindung mit jedem Browser herstellen und anzeigen Sicherheitsinformationen der Seite und Speichern einer Kopie des Zertifikats. (Google sollte Ihnen genau sagen können, was Sie für Ihren speziellen Browser tun müssen.)

Nachdem Sie das Zertifikat in einer Datei gespeichert haben, müssen Sie es dem Trust Store Ihrer JVM hinzufügen. Bei $Java_HOME/jre/lib/security/ für JREs oder $Java_HOME/lib/security für JDKs gibt es eine Datei mit dem Namen cacerts, die mit Java geliefert wird und die öffentlichen Zertifikate der bekannten Zertifizierungsstellen enthält. Um das neue Zertifikat zu importieren, führen Sie keytool als Benutzer aus, der berechtigt ist, in Zertifikate zu schreiben:

keytool -import -file <the cert file> -alias <some meaningful name> -keystore <path to cacerts file>

Es wird Sie höchstwahrscheinlich nach einem Passwort fragen. Das mit Java gelieferte Standardkennwort lautet changeit. Fast niemand ändert es. Nachdem Sie diese relativ einfachen Schritte ausgeführt haben, kommunizieren Sie sicher und mit der Gewissheit, dass Sie mit dem richtigen Server und nur mit dem richtigen Server sprechen (sofern der private Schlüssel nicht verloren geht).

124
Ryan Stewart

Nun habe ich dieses Problem auf diese Weise gelöst.

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import Java.io.OutputStream; 

// Create a trust manager that does not validate certificate chains like the default 

TrustManager[] trustAllCerts = new TrustManager[]{
        new X509TrustManager() {

            public Java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return null;
            }
            public void checkClientTrusted(Java.security.cert.X509Certificate[] certs, String authType)
            {
                //No need to implement.
            }
            public void checkServerTrusted(Java.security.cert.X509Certificate[] certs, String authType)
            {
                //No need to implement.
            }
        }
};

// Install the all-trusting trust manager
try 
{
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new Java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} 
catch (Exception e) 
{
    System.out.println(e);
}

Natürlich sollte diese Lösung nur in Szenarien verwendet werden, in denen die erforderlichen Zertifikate nicht mithilfe von keytool installiert werden können, z. Lokale Tests mit temporären Zertifikaten.

12
selladurai

Wann immer wir versuchen, eine Verbindung zu einer URL herzustellen, 

wenn der Server am anderen Standort mit dem https-Protokoll läuft und verlangt, dass wir über die im Zertifikat angegebenen Informationen kommunizieren sollen, dann Wir haben folgende Option:

1) fragen Sie nach dem Zertifikat (Zertifikat herunterladen), importieren Sie dieses Zertifikat in trustore. Die Java-Standard-Java-Verwendung von Trustore befindet sich in\Java\jdk1.6.0_29\jre\lib\security\cacerts. Wenn Sie erneut versuchen, die Verbindung zur URL herzustellen, wird die Verbindung akzeptiert.

2) In normalen Geschäftsfällen stellen wir möglicherweise eine Verbindung zu internen URLs in Organisationen her und wir wissen, dass sie korrekt sind. In solchen Fällen vertrauen Sie darauf, dass es sich um die richtige URL handelt. In solchen Fällen kann Code verwendet werden, bei dem das Zertifikat nicht für die Verbindung mit einer bestimmten URL gespeichert werden muss.

Für den Punkt Nr. 2 müssen wir folgende Schritte befolgen:

1) Schreiben Sie unterhalb der Methode, die HostnameVerifier für HttpsURLConnection festlegt, die für alle Fälle true zurückgibt, was bedeutet, dass wir dem trustStore vertrauen.

  // trusting all certificate 
 public void doTrustToCertificates() throws Exception {
        Security.addProvider(new com.Sun.net.ssl.internal.ssl.Provider());
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }
                }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                    System.out.println("Warning: URL Host '" + urlHostName + "' is different to SSLSession Host '" + session.getPeerHost() + "'.");
                }
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

2) Schreiben Sie unterhalb der Methode, die doTrustToCertificates aufruft, bevor Sie versuchen, eine Verbindung mit der URL herzustellen

    // connecting to URL
    public void connectToUrl(){
     doTrustToCertificates();//  
     URL url = new URL("https://www.example.com");
     HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
     System.out.println("ResponseCode ="+conn.getResponseCode());
   }

Dieser Aufruf gibt Antwortcode zurück = 200 bedeutet, dass die Verbindung erfolgreich ist.

Weitere Einzelheiten und ein Beispiel finden Sie unter URL .

9

Ich glaube, dass Sie versuchen, eine Verbindung zu etwas über SSL herzustellen, aber etwas, das ein Zertifikat bereitstellt, das nicht von Stammzertifizierungsstellen wie Verisign verifiziert wird. Grundsätzlich können sichere Verbindungen nur hergestellt werden, wenn der Verbindungsversuch bekannt ist die Schlüssel der Gegenparteien oder ein anderer verndor wie verisign kann einspringen und sagen, dass der bereitgestellte öffentliche Schlüssel in der Tat richtig ist.

Alle Betriebssysteme vertrauen einer Handvoll Zertifizierungsstellen, und kleinere Zertifikatsaussteller müssen von einem der großen Zertifizierer zertifiziert werden, die eine Zertifizierungskette bilden, wenn Sie bekommen, was ich meine ...

Ich komme auf den Punkt zurück .. Ich hatte ein ähnliches Problem bei der Programmierung eines Java-Applets und eines Java-Servers (hoffentlich werde ich eines Tages einen kompletten Blogpost darüber schreiben, wie ich die Sicherheit dazu gebracht habe :)) 

Im Wesentlichen musste ich die öffentlichen Schlüssel vom Server extrahieren und in einem Schlüsselspeicher in meinem Applet speichern. Als ich mich mit dem Server verband, nutzte ich diesen Schlüsselspeicher, um eine Trust-Factory und diese Trust-Factory zum Erstellen der SSL-Datei zu erstellen Verbindung. Es gibt auch andere Verfahren, wie das Hinzufügen des Schlüssels zum vertrauenswürdigen Host der JVM und das Ändern des Standard-Truststores beim Start. 

Ich habe dies vor etwa zwei Monaten getan und habe keinen Quellcode auf mich. Benutze Google und du solltest in der Lage sein, dieses Problem zu lösen. Wenn Sie mich nicht zurückschicken können und ich Ihnen den relevanten Quellcode für das Projekt zur Verfügung stellen kann. Weiß nicht, ob dies Ihr Problem löst, da Sie nicht den Code bereitgestellt haben, der diese Ausnahmen verursacht. Außerdem arbeitete ich mit Applets und dachte, ich könnte nicht verstehen, warum es auf Serverlets nicht funktioniert ...

PS: Ich kann keinen Quellcode vor dem Wochenende erhalten, da externe SSH in meinem Büro deaktiviert ist :(

0
Osama Javed

SSLHandshakeException kann auf zwei Arten aufgelöst werden.

  1. Einbindung von SSL 

    • Holen Sie sich das SSL (indem Sie den Quellsystemadministrator fragen, können Sie es auch mit dem Befehl openssl herunterladen, oder ein Browser lädt die -Zertifikate herunter.)

    • Fügen Sie das Zertifikat dem Truststore (cacerts) unter JRE/lib/security hinzu 

    • geben Sie den Truststore-Speicherort in vm-Argumenten als an. "- Djavax.net.ssl.trustStore ="

  2. SSL ignorieren

    Besuchen Sie für diese # 2 meine andere Antwort auf einer anderen stackoverflow-Website: So stellen Sie die SSL-Verifizierung in VerbindungSSL-Zertifikatfehler mit Java ignorieren

0
Amit Kaneria