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