web-dev-qa-db-fra.com

comment capturer https avec fiddler, dans java

J'exécute le programme Java Java dans l'IDE Eclipse:

import Java.net.*;
import Java.io.*;

public class HH
{
    public static void main(String[] args) throws Exception
    {
        //if i comment out the system properties, and don't set any jvm arguments, the program runs and prints out the html fine.
        System.setProperty("http.proxyHost", "localhost"); 
        System.setProperty("http.proxyPort", "8888"); 
        System.setProperty("https.proxyHost", "localhost"); 
        System.setProperty("https.proxyPort", "8888"); 

        URL x = new URL("https://www.google.com");
        HttpURLConnection hc = (HttpURLConnection)x.openConnection();

        hc.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.0)
        AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2");

        InputStream is = hc.getInputStream();

        int u = 0;
        byte[] kj = new byte[1024];
        while((u = is.read(kj)) != -1)
        {
            System.out.write(kj,0,u);
        }
        is.close();
    }
}

Cela produit l'exception suivante, si le violoniste est en cours d'exécution, à la fois pendant la capture et non la capture:

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 com.Sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at com.Sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown ...

Si je ferme fiddler, le programme fonctionne très bien sans aucune exception, produisant le html sur l'URL à laquelle je me connecte.

alternativement, si je spécifie System.setProperty("https.proxyPort", "443");, au lieu de: System.setProperty("https.proxyPort", "8888");, il s'exécute et imprime tout le code html, sans exception, même lorsque le violon est ouvert, en mode capture, mais il n'y a toujours pas de capturer du violoneux du tout.

Ensuite, si je définis ces propriétés système via les arguments jvm d'Eclipse comme: -DproxySet=true -DproxyHost=127.0.0.1 -DproxyPort=8888, La même exception exacte se produit à nouveau, tant que l'application violon est en cours d'exécution, en mode capture et non capture. Si je ferme violon, le programme fonctionnera parfaitement.

Si j'utilise: System.setProperty("http.proxyHost", "127.0.0.1"); au lieu de: System.setProperty("http.proxyHost", "localhost");, cela fonctionne très bien avec l'application fiddler en cours, à la fois en mode capture/non capture, mais également AUCUN trafic capturé.

Quelqu'un est-il là-bas, capable de capturer son propre trafic https avec fiddler, PAS via un navigateur Web, mais via un programme Java? Quels sont les arguments jvm, comment le configurez-vous pour le faire ça? merci

50
Sam Adamsh

Créez un magasin de clés contenant le certificat Fiddler. Utilisez ce fichier de clés comme fichier de clés de confiance pour la machine virtuelle Java avec les paramètres de proxy.

Voici comment procéder:

  • Exporter le certificat racine de Fiddler

Outils -> Options Fiddler ... -> HTTPS -> Exporter le certificat racine vers le bureau

  • Créer un magasin de clés avec ce certificat

Ouvrir la ligne de commande en tant qu'administrateur (keytool ne fonctionne pas autrement)

<JDK_Home>\bin\keytool.exe -import -file C:\Users\<Username>\Desktop\FiddlerRoot.cer -keystore FiddlerKeystore -alias Fiddler

Entrez un mot de passe lorsque vous y êtes invité. Cela devrait créer un fichier appelé FiddlerKeystore.

  • Démarrez maintenant la JVM avec Fiddler comme proxy et ce magasin de clés comme magasin de confiance. Vous aurez besoin de ces vmargs:

-DproxySet = true

-DproxyHost = 127.0.0.1

-DproxyPort = 8888

-Djavax.net.ssl.trustStore = <chemin\vers\FiddlerKeystore>

-Djavax.net.ssl.trustStorePassword = <Mot de passe du magasin de clés>

Utilisez ces vmargs dans votre configuration d'exécution Eclipse et vous devriez être prêt à partir.

Je suis en mesure de capturer les demandes HTTPS effectuées à partir de la JVM sans aucun problème avec cette configuration.

98
CodeMangler

Vous pouvez également importer la clé du violon dans Java magasin de certificats de confiance:

  1. Exporter le certificat racine de Fiddler

    Outils -> Options du violoneux ... -> HTTPS -> Actions -> Exporter le certificat racine vers le bureau

  2. Exécutez en tant qu'administrateur:

"keytool.exe" -import -noprompt -trustcacerts -alias FiddlerRoot -file c:\work\FiddlerRoot.cer -keystore "C:\Program Files\Java\jdk1.7.0_79\jre\lib\security\cacerts" -storepass changes le

J'ai également eu un problème avec le décryptage du trafic https de Google API Client avec Fiddler. Le problème était que par défaut, il utilise son propre magasin de certificats:

InputStream keyStoreStream = GoogleUtils.class.getResourceAsStream("google.jks");
SecurityUtils.loadKeyStore(certTrustStore, keyStoreStream, "notasecret");

Et voici comment j'ai corrigé cela:

 HttpTransport transport = new NetHttpTransport() 
 //istead of transport = GoogleNetHttpTransport.newTrustedTransport();
4
zenden2k

Créez un magasin de clés contenant le certificat du violoneux et utilisez-le:

Java -DproxySet=true -DproxyHost=127.0.0.1 -DproxyPort=8888 -Dhttps.proxyPort=8888 -Dhttps.proxyHost=127.0.0.1 -Djavax.net.ssl.trustStore=<path to FiddlerKeystore> -Djavax.net.ssl.trustStorePassword=<password> -jar test.jar

Si vous utilisez des bibliothèques HTTP tierces, vous devez définir les proxys de connexion. Exemple avec Apache Commons HttpClient:

HttpClient httpClient = new HttpClient();
httpClient.getHostConfiguration().setProxy("localhost", 8888);

MISE À JOUR:

si vous utilisez Apache HttpClient 4.5.5 ou une version plus récente, vous devez le faire comme ceci:

HttpHost proxy = new HttpHost("localhost", 8888, "http");
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
CloseableHttpClient httpclient = HttpClients.custom()
                .setRoutePlanner(routePlanner)
                .build();
4
Dimmduh

J'ai trouvé que j'avais également besoin des options de ligne de commande suivantes Java

-Dhttps.proxyPort=8888 
-Dhttps.proxyHost=127.0.0.1
2
Brook