Как захватить HTTPS с Fiddler, в Java - PullRequest
49 голосов
/ 18 декабря 2011

Я использую следующую Java-программу в Eclipse IDE:

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

Это приводит к следующему исключению, если fiddler работает, как во время захвата, так и без захвата:

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 ...

Если я закрою fiddler, программа будет работать без каких-либо исключений, создавая HTML-код для URL, к которому я подключаюсь.

в качестве альтернативы, если я укажу System.setProperty("https.proxyPort", "443"); вместо: System.setProperty("https.proxyPort", "8888");, он запускает и печатает все html, без исключения, даже когда открыт фиддлер, в режиме захвата, но захват от фиддлера по-прежнему отсутствует .

Тогда, если я установлю эти системные свойства через аргументы jvm eclipse, такие как: -DproxySet=true -DproxyHost=127.0.0.1 -DproxyPort=8888, то же самое точное исключение произойдет снова, пока приложение fiddler работает, как в режиме захвата, так и в режиме без захвата. Если я закрою Fiddler, программа будет работать отлично.

Если я использую: System.setProperty("http.proxyHost", "127.0.0.1"); вместо: System.setProperty("http.proxyHost", "localhost");, он отлично работает с запущенным приложением fiddler, как в режиме захвата / захвата, так и без захваченного трафика.

Кто-нибудь может захватить собственный https-трафик с помощью fiddler, НЕ через веб-браузер, а через java-программу? Каковы аргументы jvm, как вы это настроите? спасибо

Ответы [ 4 ]

97 голосов
/ 21 декабря 2011

Создать хранилище ключей, содержащее сертификат Fiddler.Используйте это хранилище ключей в качестве хранилища доверенных сертификатов для JVM вместе с настройками прокси.

Вот как это сделать:

  • Экспорт корневого сертификата Fiddler

Инструменты -> Параметры Fiddler ... -> HTTPS -> Экспорт корневого сертификата на рабочий стол

  • Создать хранилище ключей с этим сертификатом

Откройте командную строку как администратор (иначе не будет работать keytool)

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

Введите пароль при появлении запроса.Это должно создать файл с именем FiddlerKeystore.

  • Теперь запустите JVM с Fiddler в качестве прокси и этим хранилищем ключей в качестве хранилища доверенных сертификатов.Вам понадобятся следующие vmargs:

-DproxySet = true

-DproxyHost = 127.0.0.1

-DproxyPort = 8888

-Djavax.net.ssl.trustStore =

-Djavax.net.ssl.trustStorePassword =

Используйте эти vmargs в вашей конфигурации запуска затмения, и вы должны быть в порядке.

Я могу захватывать HTTPS-запросы, сделанные от JVM, без каких-либо проблем с этой настройкой.

4 голосов
/ 13 ноября 2015

Вы также можете импортировать ключ фиддлера в хранилище доверенных сертификатов Java:

  1. Экспорт корневого сертификата Fiddler

    Инструменты -> Параметры Fiddler ... -> HTTPS -> Действия -> Экспорт корневого сертификата на рабочий стол

  2. Запуск от имени администратора:

"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 "-стандартный

Также у меня была проблема с расшифровкой https-трафика Google API Client с помощью Fiddler. Проблема заключалась в том, что по умолчанию он использует собственный магазин сертификатов:

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

И вот как я это исправил:

 HttpTransport transport = new NetHttpTransport() 
 //istead of transport = GoogleNetHttpTransport.newTrustedTransport();
4 голосов
/ 25 сентября 2014

Создайте хранилище ключей, содержащее сертификат Fiddler, и используйте его:

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

Если вы используете сторонние HTTP-библиотеки, вам необходимо установить прокси подключения.Пример с Apache Commons HttpClient:

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

ОБНОВЛЕНИЕ:

если вы используете Apache HttpClient 4.5.5 или новее, вам нужно сделать это следующим образом:

HttpHost proxy = new HttpHost("localhost", 8888, "http");
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
CloseableHttpClient httpclient = HttpClients.custom()
                .setRoutePlanner(routePlanner)
                .build();
2 голосов
/ 22 марта 2012

Я обнаружил, что мне также необходимы следующие параметры командной строки Java

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