Comment se connecter via HTTPS en utilisant Jsoup?

ça marche très bien sur HTTP, mais quand j'essaie D'utiliser une source HTTPS, ça lance l'exception suivante:

10-12 13:22:11.169: WARN/System.err(332): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
10-12 13:22:11.179: WARN/System.err(332):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:477)
10-12 13:22:11.179: WARN/System.err(332):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:328)
10-12 13:22:11.179: WARN/System.err(332):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.setupSecureSocket(HttpConnection.java:185)
10-12 13:22:11.179: WARN/System.err(332):     at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:433)
10-12 13:22:11.189: WARN/System.err(332):     at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeConnection(HttpsURLConnectionImpl.java:378)
10-12 13:22:11.189: WARN/System.err(332):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:205)
10-12 13:22:11.189: WARN/System.err(332):     at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:152)
10-12 13:22:11.189: WARN/System.err(332):     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:377)
10-12 13:22:11.189: WARN/System.err(332):     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:364)
10-12 13:22:11.189: WARN/System.err(332):     at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:143)

voici le code correspondant:

try {
    doc = Jsoup.connect("https url here").get();
} catch (IOException e) {
    Log.e("sys","coudnt get the html");
    e.printStackTrace();
}
20
demandé sur jfisk 2011-10-12 21:29:23

8 réponses

si vous voulez le faire de la bonne façon, et/ou vous devez traiter avec un seul site, alors vous avez essentiellement besoin de saisir le certificat SSL du site en question et de l'importer dans votre boutique Java key. Il en résultera un fichier JKS que vous définirez à votre tour comme étant SSL trust store avant d'utiliser Jsoup (ou java.net.URLConnection ).

vous pouvez prendre le certificat de votre magasin webbrowser. Supposons que vous utilisez Firefox.

  1. Go sur le site en question en utilisant Firefox, qui est dans votre cas https://web2.uconn.edu/driver/old/timepoints.php?stopid=10
  2. à gauche dans la barre d'adresse vous verrez "uconn.edu "en bleu (Ceci indique un certificat SSL valide)
  3. Cliquez dessus pour plus de détails, puis cliquez sur le Plus d'informations bouton.
  4. dans le dialogue de sécurité qui apparaît, cliquez sur la vue Certificat bouton.
  5. dans le panneau de certificat qui apparaît, allez à l'onglet détails .
  6. cliquez sur l'élément le plus profond de la hiérarchie des certificats, qui est dans ce cas "web2.uconn.edu" et enfin cliquez sur le bouton exporter .

Maintenant vous avez un fichier web2.uconn.edu.crt .

Ensuite, ouvrez la commande prompt et importez-la dans le Java key store à l'aide de la commande keytool (elle fait partie du JRE):

keytool -import -v -file /path/to/web2.uconn.edu.crt -keystore /path/to/web2.uconn.edu.jks -storepass drowssap

le -file doit pointer vers l'emplacement du fichier .crt que vous venez de télécharger. Le -keystore doit pointer vers L'emplacement du fichier .jks généré (que vous voulez à votre tour Définir comme le SSL trust store). Le -storepass est nécessaire, vous pouvez simplement entrer n'importe quel mot de passe que vous voulez aussi longtemps qu'il est au moins 6 caractères.

Maintenant, vous avez un fichier web2.uconn.edu.jks . Vous pouvez enfin le Définir comme SSL trust store avant de vous connecter comme suit:

System.setProperty("javax.net.ssl.trustStore", "/path/to/web2.uconn.edu.jks");
Document document = Jsoup.connect("https://web2.uconn.edu/driver/old/timepoints.php?stopid=10").get();
// ...

comme une alternative complètement différente, en particulier lorsque vous avez besoin de traiter avec plusieurs sites (i.e. vous créez un World wide Web crawler), alors vous pouvez également donner des instructions à Jsoup (essentiellement, java.net.URLConnection ) de faire confiance aveuglément à tous les certificats SSL. Voir aussi la section "Gestion des sites HTTPS non sécurisés ou mal configurés" en bas de page de cette réponse: en utilisant java.net.URLConnection to fire and handle HTTP requests

49
répondu BalusC 2017-05-23 11:47:01

j'ai trébuché sur les réponses ici et dans la question liée dans ma recherche et je veux ajouter deux éléments d'information, car la réponse acceptée ne correspond pas à mon scénario tout à fait similaire, mais il y a une solution supplémentaire qui correspond même dans ce cas (cert et hostname ne correspondent pas aux systèmes de test).

  1. il y a une requête github pour ajouter une telle fonctionnalité. Alors peut-être que bientôt le problème sera résolu: https://github.com/jhy/jsoup/pull/343 edit: Github demande a été résolu et la méthode pour désactiver la validation du certificat est: validateTLSCertificates(boolean valider)
  2. basé sur http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections / j'ai trouvé une solution qui semble fonctionner (au moins dans mon scénario où jsoup 1.7.3 est appelé dans le cadre d'une tâche maven). J'ai enveloppé dans une méthode disableSSLCertCheck() que j'appelle avant la première Jsoup.connecter.)(

avant d'utiliser cette méthode , vous devriez être vraiment sûr que vous comprenez ce que vous faites là - bas-ne pas vérifier les certificats SSL est une chose vraiment stupide. Utilisez toujours les certificats SSL corrects pour vos serveurs qui sont signés par une AC généralement acceptée. Si vous ne pouvez pas vous permettre un CA généralement accepté utiliser des certificats SSL corrects néanmoins avec @BalusC accepté réponse ci-dessus. Si vous ne pouvez pas configurer correctement SSL certificats (CE qui ne devrait jamais être le cas dans les environnements de production) la méthode suivante pourrait fonctionner:

    private void disableSSLCertCheck() throws NoSuchAlgorithmException, KeyManagementException {
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }
    };

    // Install the all-trusting trust manager
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    // Install the all-trusting host verifier
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    }
7
répondu NextThursday 2015-11-03 00:28:12

dans mon cas, tout ce que je devais faire était d'ajouter le .validateTLSCertificates(false) dans ma connexion

Document doc  = Jsoup.connect(httpsURLAsString)
            .timeout(60000).validateTLSCertificates(false).get();

j'ai également eu à augmenter le délai d'attente, mais je pense que ce n'est pas pertinent

4
répondu johnmerm 2018-01-16 09:40:30

j'ai eu le MÊME PROBLÈME MAIS j'ai pris la route paresseuse - dites à votre application d'ignorer le cert et continuer de toute façon.

j'ai le code d'ici: comment utiliser une URL locale HTTPS en java?

vous devrez importer ces classes pour que cela fonctionne:

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

il suffit d'exécuter cette méthode quelque part avant d'essayer de faire la connexion et voilà, il fait confiance au cert quoi qu'il arrive. Bien sûr, cela n'est pas une aide si vous voulez réellement s'assurer que le cert est réel, mais bon pour la surveillance de vos propres sites Web internes, etc.

2
répondu RobinCJ 2017-05-23 12:09:39

Je ne suis pas un expert dans ce domaine, mais j'ai rencontré une exception similaire en essayant de se connecter à un site web sur HTTPS en utilisant java.net APIs. Le navigateur fait beaucoup de travail pour vous en ce qui concerne les certificats SSL lorsque vous visitez un site en utilisant HTTPS. Cependant, lorsque vous vous connectez manuellement à des sites (en utilisant des requêtes HTTP manuellement), tout ce travail doit encore être fait. Maintenant je ne sais pas ce que tout ce travail est exactement, mais il a à voir avec le téléchargement des certificats et de les mettre où Java peut les trouver. Voici un lien qui nous l'espérons vous pointer dans la bonne direction.

http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services

0
répondu jeff 2011-10-12 17:43:39

je faisais face au même problème avec Jsoup, Je n'ai pas pu me connecter et obtenir le document pour les urls https mais quand j'ai changé ma version JDK de 1.7 à 1.8, le problème a été résolu.

Ça peut vous aider :)

0
répondu ramkishorbajpai 2018-02-22 14:11:54

j'ai eu ce problème seulement dans l'environnement dev. La solution pour le résoudre était juste d'ajouter quelques drapeaux pour ignorer SSL à VM:

-Ddeployment.security.TLSv1.1=false 
-Ddeployment.security.TLSv1.2=false
0
répondu pawelini1 2018-08-04 08:42:37

essayez de suivre (mettez-le juste avant Jsoup.connect("https://example.com") :

    Authenticator.setDefault(new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password.toCharArray());
        }
    });
-5
répondu RomKazanova 2014-12-11 10:36:27