Как захватить https с помощью скрипача, в java
Я запускаю следующую 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 является RUNNING, как во время захвата, так и без захвата:
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 без исключений, даже если скрипт открыт, в режиме захвата, но до сих пор нет захвата от скрипача вообще.
Затем, если я установил эти системные свойства через аргументы eclipse jvm, такие как: -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-трафик с помощью скрипача, а не через веб-браузер, а через java-программу? Каковы аргументы jvm, как вы это настроили? спасибо
Ответы
Ответ 1
Создайте хранилище ключей, содержащее сертификат Fiddler.
Используйте это хранилище ключей как доверенное хранилище для JVM вместе с настройками прокси.
Вот как это сделать:
- Экспорт корневого сертификата Fiddler
Инструменты → Параметры Fiddler... → HTTPS → Экспорт корневого сертификата на рабочий стол
- Создайте хранилище ключей с этим сертификатом
Откройте командную строку как администратор (keytool не работает иначе)
< JDK_Home > \bin\keytool.exe -import -file C:\Users\<Username> \Desktop\FiddlerRoot.cer -keystore FiddlerKeystore -alias Fiddler
Введите пароль при появлении запроса. Это должно создать файл под названием FiddlerKeystore.
- Теперь запустите JVM с помощью Fiddler в качестве прокси-сервера, и это хранилище ключей в качестве доверенного магазина. Вам понадобятся эти vmargs:
-DproxySet = истина
-DproxyHost = 127.0.0.1
-DproxyPort = 8888
-Djavax.net.ssl.trustStore = < путь\к\FiddlerKeystore >
-Djavax.net.ssl.trustStorePassword = < Пароль ключa >
Используйте эти vmargs в конфигурации запуска eclipse, и вам должно быть хорошо идти.
Я могу записывать HTTPS-запросы из JVM без каких-либо проблем с этой настройкой.
Ответ 2
Создайте хранилище ключей, содержащее сертификат 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);
Ответ 3
Я обнаружил, что мне также необходимы следующие параметры командной строки java
-Dhttps.proxyPort=8888
-Dhttps.proxyHost=127.0.0.1
Ответ 4
Вы также можете импортировать ключ fiddler в хранилище доверенных сертификатов java:
-
Экспорт корневого сертификата Fiddler
Инструменты → Параметры Fiddler... → HTTPS → Действия → Экспорт корневого сертификата на рабочий стол
-
Запуск от имени администратора:
"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 changeit
Также у меня возникла проблема с расшифровкой https-трафика клиента API Google с помощью Fiddler.
Проблема заключалась в том, что по умолчанию он использует собственный хранилище cert:
InputStream keyStoreStream = GoogleUtils.class.getResourceAsStream("google.jks");
SecurityUtils.loadKeyStore(certTrustStore, keyStoreStream, "notasecret");
И вот как я исправил это:
HttpTransport transport = new NetHttpTransport()
//istead of transport = GoogleNetHttpTransport.newTrustedTransport();