Telechargement fichier depuis url en https

Résolu/Fermé
Signaler
Messages postés
34237
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
6 décembre 2021
-
Messages postés
20
Date d'inscription
lundi 21 mars 2016
Statut
Membre
Dernière intervention
19 mai 2017
-
Bonjour,

J'essaye de télécharger un fichier depuis une url en https
https://machintruc.fr/bidule/monfichier.xls

NB: L'url a été modifiée depuis peu (n'était pas en https mais http tout court ) et le script fonctionnait parfaitement avant ce changement

Voici le code utilisé
private void getA()
    throws Exception
  {
    Utilitaire.afficherCommentaire("Recuperation de " + this.filenameA);
    System.setProperty("http.auth.ntlm.domain", domaine);
    
    System.out.println("URL=" + adresseA);
    URL url = new URL(adresseA);
    URLConnection uc = url.openConnection();
    int contentLength = uc.getContentLength();
    InputStream raw = uc.getInputStream();
    InputStream in = new BufferedInputStream(raw);
    byte[] data = new byte[contentLength];
    int bytesRead = 0;
    int offset = 0;
    while (offset < contentLength)
    {
      bytesRead = in.read(data, offset, data.length - offset);
      if (bytesRead == -1) {
        break;
      }
      offset += bytesRead;
    }
    in.close();
    if (offset != contentLength) {
      throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes");
    }
    FileOutputStream out = new FileOutputStream(this.filenameA);
    out.write(data);
    out.flush();
    out.close();
  }
  



J'avais un Message d'erreur :
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target


J'ai donc suivi quelques docs sur le net indiquant qu'il suffisait d'installer le certificat du site dans le jdk/jre .... chose faite.
keytool -keystore cacerts -importcert -alias moncert -file d:\temp\moncert.cer


Mais maintenant... j'obtiens l'erreur : Server redirected too many times (20)


Auriez-vous, oh grands manitous du java..., une idée sur les causes du problème et un moyen d'y remédier ?


2 réponses

Messages postés
34237
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
6 décembre 2021
3 862
Bon ben j'ai trouvé....
mauvaise chaine de "login"..... j'avais oublié de doubler mes "\"
Messages postés
16439
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
1 décembre 2021
2 920
12 minutes pour trouver ton problème tout seul, tu m'excuseras de ne pas être intervenu en temps utiles ^^

Remarque : plutôt que d'enregistrer le certificat du site dans le JDK (et donc de devoir le faire autant de fois qu'il y a de site à vérifier) il est plus intéressant d'enregistrer le certificat racine, afin d'autoriser tout les sites certifiés par cet organisme (s'il est fiable bien sûr).

Java connaît la plupart des autorités de certifications "standards" (VeriSign, GeoTrust, etc) ce qui couvre la plupart des sites https du web. Et régulièrement lors de mises à jours Java, de nouveaux certificats sont rajoutés.
Mais effectivement si le site est signé par un certificat maison... il faut le rajouter à la main.

On peut aussi (mais c'est plus moche) forcer Java à ignorer la vérification du certificat, un peu comme on peut le faire avec un navigateur web lorsque le https est "suspect".
Messages postés
34237
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
6 décembre 2021
3 862 >
Messages postés
16439
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
1 décembre 2021

Hello ^^


12 minutes pour trouver ton problème tout seul, tu m'excuseras de ne pas être intervenu en temps utiles ^^

C'est 12 minutes fictives.... j'ai cherché une bonne parti de la soirée hier avant de me décider de poster ma question....
Et puis... (c'est souvent mon cas....) au moment de poster ma question... hop...un moment de lucidité.... :-)


il est plus intéressant d'enregistrer le certificat racine, afin d'autoriser tout les sites certifiés par cet organisme (s'il est fiable bien sûr).

C'est en effet ce que j'ai fait.


On peut aussi (mais c'est plus moche) forcer Java à ignorer la vérification du certificat, un peu comme on peut le faire avec un navigateur web lorsque le https est "suspect".

J'y avait pensé .. mais je n'ai pas trouvé (sans avoir trop cherché de toutes façons..) comment faire.
A la limite... si tu as cette technique sous la main.. ça m'interesse quand même....
Messages postés
16439
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
1 décembre 2021
2 920
Déjà, je ne sais pas si c'est exactement lié mais il y a cette option globale :
https://java.com/en/download/help/revocation_options.html

Cependant, je pense que pour un utilisateur lambda, faire cette manipulation est un peu compliqué, il en va de même pour l'installation du certificat dans sa JRE.

Programmatiquement on peut ignorer la certification en faisant une surcharge des méthodes de vérification et faire en sorte qu'elles acceptent toujours tout.

Remarque : cette méthode permet également de renforcer la sécurité en analysant plus finement le contenu des certificats pour éventuellement rajouter des règles de contrôles supplémentaires (par exemple pour ne contourner la sécurité que pour une URL particulière).

Exemple :

package ccm;

import java.net.*;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import javax.net.ssl.*;

class FakeTrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        System.out.println("# checkClientTrusted: " + authType);
        System.out.println(Arrays.toString(chain));
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        System.out.println("# checkServerTrusted: " + authType);
        System.out.println(Arrays.toString(chain));
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        System.out.println("# getAcceptedIssuers");
        return null;
    }
}

public class TestHttps {

    public static void disableSSL() {
        try {
            SSLContext ssl = SSLContext.getInstance("SSL");
            TrustManager[] tm = { new FakeTrustManager() };
            ssl.init(null, tm, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(ssl.getSocketFactory());
        } catch (RuntimeException | NoSuchAlgorithmException | KeyManagementException e) {
            throw new SecurityException("Can't disable SSL", e);
        }
    }

    public static void main(String[] args) throws Exception {
        disableSSL();
        Scanner sc = new Scanner(new URL("https://www.google.fr/").openStream());
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            // System.out.println(line);
        }
        sc.close();
    }
}

NB. j'ai pris https://www.google.fr comme exemple pour voir le contenu des certificats, en sachant que de toute façon Java accepte déjà le certificat de Google.
C'est à tester sur ton site récalcitrant ;-)
Messages postés
34237
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
6 décembre 2021
3 862 >
Messages postés
16439
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
1 décembre 2021

Super.
Merci m'sieur. Je jetterai un oeil là dessus prochainement et te ferai un petit retour.
Messages postés
20
Date d'inscription
lundi 21 mars 2016
Statut
Membre
Dernière intervention
19 mai 2017

Merci j'ai vu l'exemple c'est bien comme source
encore une fois merci pour votre disponibilite