Hoe javax.net.ssl.SSLHandshakeException-fout op te lossen?

Ik heb verbinding gemaakt met VPN om de inventaris-API in te stellen om een productlijst te krijgen en het werkt prima. Zodra ik het resultaat van de webservice krijg en ik bind aan de gebruikersinterface. En ook heb ik PayPal geïntegreerd met mijn applicatie voor Express checkout wanneer ik bel voor betaling. Ik word geconfronteerd met deze fout. Ik gebruik servlet voor back-end proces. Kan iemand zeggen hoe dit probleem op te lossen?

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

Antwoord 1, autoriteit 100%

Eerst moet u het openbare certificaat verkrijgen van de server waarmee u verbinding probeert te maken. Dat kan op verschillende manieren, zoals contact opnemen met de serverbeheerder en erom vragen, met OpenSSL om het te downloaden, of, aangezien dit een HTTP-server lijkt te zijn, er verbinding mee te maken met een willekeurige browser, de beveiligingsinformatie van de pagina te bekijken en een kopie van het certificaat op te slaan. (Google zou u precies moeten kunnen vertellen wat u voor uw specifieke browser moet doen.)

Nu u het certificaat in een bestand hebt opgeslagen, moet u het toevoegen aan de vertrouwensopslag van uw JVM. Op $JAVA_HOME/jre/lib/security/voor JRE’s of $JAVA_HOME/lib/securityvoor JDK’s staat een bestand met de naam cacerts, dat wordt geleverd met Java en bevat de openbare certificaten van de bekende Certificerende Autoriteiten. Om het nieuwe certificaat te importeren, voert u keytool uit als een gebruiker die toestemming heeft om naar cacerts te schrijven:

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

Het zal u hoogstwaarschijnlijk om een wachtwoord vragen. Het standaardwachtwoord zoals geleverd bij Java is changeit. Bijna niemand verandert het. Nadat u deze relatief eenvoudige stappen heeft voltooid, communiceert u veilig en met de zekerheid dat u met de juiste server praat en alleen met de juiste server (zolang ze hun privésleutel niet verliezen).


Antwoord 2, autoriteit 11%

Nu heb ik dit probleem op deze manier opgelost,

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);
}

Natuurlijk mag deze oplossing alleen worden gebruikt in scenario’s waarin het niet mogelijk is om de vereiste certificaten te installeren met behulp van keytool, b.v. lokale testen met tijdelijke certificaten.


Antwoord 3, autoriteit 7%

Telkens wanneer we proberen verbinding te maken met de URL,

Als de server op de andere site draait op het https-protocol en verplicht is om te communiceren via informatie die in het certificaat wordt verstrekt, dan
we hebben de volgende optie:

1) vraag om het certificaat (download het certificaat), importeer dit certificaat in trustore. Het standaardgebruik van Trustore Java is te vinden in \Java\jdk1.6.0_29\jre\lib\security\cacerts, en als we opnieuw proberen verbinding te maken met de URL, wordt de verbinding geaccepteerd.

2) In normale zakelijke gevallen maken we mogelijk verbinding met interne URL’s in organisaties en weten we dat deze correct zijn.
In dergelijke gevallen vertrouwt u erop dat dit de juiste URL is. In de bovenstaande gevallen kan code worden gebruikt die niet verplicht is om het certificaat op te slaan om verbinding te maken met een bepaalde URL.

voor punt 2 moeten we onderstaande stappen volgen:

1) schrijf de onderstaande methode op die HostnameVerifier instelt voor HttpsURLConnection die true retourneert voor alle gevallen, wat betekent dat we de trustStore vertrouwen.

 // 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) schrijf onderstaande methode, die doTrustToCertificates aanroept voordat wordt geprobeerd verbinding te maken met de URL

   // 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());
   }

Deze oproep retourneert de responscode = 200 betekent dat de verbinding is geslaagd.

Voor meer details en voorbeeldvoorbeelden kun je verwijzen naar URL.


Antwoord 4

SSLHandshakeException kan op 2 manieren worden opgelost.

  1. SSL integreren

    • Verkrijg de SSL (door de bronsysteembeheerder te vragen, kan ook
      worden gedownload met de opdracht openssl, of elke browser downloadt de
      certificaten)

    • Voeg het certificaat toe aan truststore (cacerts) op
      JRE/lib/beveiliging

    • geef de truststore-locatie op in vm-argumenten als
      “-Djavax.net.ssl.trustStore=”

  2. SSL negeren

    Ga voor deze #2 naar mijn andere antwoord op een andere stackoverflow-website:
    SSL-verificatie negeren SSL-certificaatfouten negeren met Java


Antwoord 5

Ik denk dat je probeert verbinding te maken met iets dat SSL gebruikt, maar dat iets een certificaat levert dat niet is geverifieerd door rootcertificeringsinstanties zoals verisign.. In wezen kunnen standaard beveiligde verbindingen alleen tot stand worden gebracht als de persoon die probeert om verbinding te maken weet dat de sleutels van de tegenpartij of een andere verndor zoals verisign kan ingrijpen en kan zeggen dat de openbare sleutel die wordt verstrekt inderdaad juist is..

ALLE besturingssystemen vertrouwen erop dat een handvol certificeringsinstanties en kleinere certificaatuitgevers gecertificeerd moeten worden door een van de grote certificeerders die een keten van certificeerders vormen, als u begrijpt wat ik bedoel…

Hoe dan ook, terugkomend op het punt.. Ik had een soortgelijk probleem bij het programmeren van een java-applet en een java-server (Hopelijk zal ik ooit een volledige blogpost schrijven over hoe ik alle beveiliging heb laten werken :))

In wezen moest ik de openbare sleutels van de server extraheren en opslaan in een sleutelarchief in mijn applet en toen ik verbinding maakte met de server, gebruikte ik dit sleutelarchief om een vertrouwensfabriek te creëren en die vertrouwensfabriek om maak de ssl-verbinding. Er zijn ook alternatieve procedures, zoals het toevoegen van de sleutel aan de vertrouwde host van de JVM en het wijzigen van de standaard trust store bij het opstarten.

Ik heb dit ongeveer twee maanden geleden gedaan en heb nu geen broncode bij me. Gebruik google en je zou dit probleem moeten kunnen oplossen. Als je me geen bericht kunt sturen, kan ik je de relevante broncode voor het project geven. Weet niet of dit je probleem oplost, omdat je de code die deze uitzonderingen veroorzaakt niet hebt verstrekt. Verder werkte ik met applets, waarvan ik dacht dat ik niet kon zien waarom het niet zou werken op Serverlets…

P.S. Ik krijg de broncode niet voor het weekend omdat externe SSH is uitgeschakeld in mijn kantoor 🙁


Antwoord 6

Nu heb ik dit probleem op deze manier opgelost,

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);
}

Other episodes