Téléchargement de fichier SSLHandshakeException


Lorsque j'essaie de télécharger par programme un fichier en utilisant du code Java, je reçois une exception:

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 sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1513)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    at java.net.URL.openStream(URL.java:1045)
    at DownloadFileExample.download(DownloadFileExample.java:15)
    at DownloadFileExample.main(DownloadFileExample.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
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:387)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
    ... 20 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
    ... 26 more

Voici mon code, y compris le fichier que je veux télécharger:

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class DownloadFileExample
{
    public static void download(String downloadURL) throws IOException
    {
        URL website = new URL(downloadURL);
        String fileName = "downloaded.zip";

        try (InputStream inputStream = website.openStream())
        {
            Files.copy(inputStream, Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING);
        }
    }

    public static void main(String[] arguments) throws IOException
    {
        String downloadURL = "https://mh-nexus.de/downloads/HxDSetupEN.zip";
        download(downloadURL);
    }
}

J'ai essayé de télécharger en utilisant le protocole HTTP au début mais cela me donne un code d'état 301 moved permanently donc j'ai réalisé qu'il redirige vers HTTPS. Cependant, HTTPS me donne le SSLHandshakeException d'en haut. En utilisant un navigateur, le téléchargement fonctionne parfaitement. Comment télécharger le fichier correctement en utilisant du code Java?

Author: BullyWiiPlaza, 2016-06-01

2 answers

Cela se produit parce que le certificat https://mh-nexus.de le site Web n'est pas sur la liste blanche de votre JRE

Options

1) Inclure le certificat de serveur dans la liste blanche JRE (jre / lib / security / cacerts)    Pour télécharger le certificat du serveur, ouvrez le site avec le navigateur, faites un clic droit sur le verrou vert, sélectionnez "afficher le certificat" et téléchargez

Le moyen le plus simple d'explorer cacerts et d'importer un certificat de confiance est d'utiliser un outil GUI comme portecle ( http://portecle.sourceforge.net / ). Vous pouvez également utiliser keytool

keytool -import -trustcacerts -keystore /opt/java/jre/lib/security/cacerts -alias mycert -noprompt -storepass changeit -file /tmp/examplecert.crt

Voir Comment importer correctement un certificat auto-signé dans Java keystore qui est disponible par défaut pour toutes les applications Java?

2) Utilisez votre propre truststore et inclure le certificat de serveur

System.setProperty ("javax.net.ssl.trustStore" path_to_your_cacerts_file);

3) N'utilisez pas du tout truststore (réponse BullyWiiPlaza)

 2
Author: pedrofb, 2017-05-23 11:58:42

D'accord, j'ai donc trouvé la solution ici. J'ai simplement besoin d'installer un de confiance SSL certificat TrustManager. Ce n'est généralement pas une bonne idée mais sert bien à mon but.

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

public class DownloadFileExample
{
    public static void download(String downloadURL) throws IOException
    {
        URL website = new URL(downloadURL);
        String fileName = "downloaded.zip";

        try (InputStream inputStream = website.openStream())
        {
            Files.copy(inputStream, Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING);
        }
    }

    private static void trustAllCertificates() throws NoSuchAlgorithmException, KeyManagementException
    {
        TrustManager[] trustManagers = new TrustManager[]{new X509TrustManager()
        {
            public X509Certificate[] getAcceptedIssuers()
            {
                return new X509Certificate[0];
            }

            public void checkClientTrusted(
                    X509Certificate[] certs, String authType)
            {
            }

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

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustManagers, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
    }

    public static void main(String[] arguments) throws IOException, NoSuchAlgorithmException, KeyManagementException
    {
        trustAllCertificates();

        String downloadURL = "https://mh-nexus.de/downloads/HxDSetupEN.zip";
        download(downloadURL);
    }
}
 0
Author: BullyWiiPlaza, 2017-05-23 12:15:57