如何在java中用fiddler捕获https

时间:2011-12-18 04:07:10

标签: java eclipse https fiddler

我在Eclipse IDE中运行以下java程序:

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,程序运行正常,没有任何异常,在我连接的url上生成html。

或者,如果我指定System.setProperty("https.proxyPort", "443");,而不是:System.setProperty("https.proxyPort", "8888");,它会运行并打印出所有html,无需例外,即使在fiddler打开时,在捕获模式下,但仍然没有捕获来自小提琴手。

然后,如果我通过eclipse的jvm参数设置这些系统属性,例如:-DproxySet=true -DproxyHost=127.0.0.1 -DproxyPort=8888,只要fiddler应用程序在捕获和非捕获模式下运行,就会再次发生同样的异常。如果我关闭提琴手,该程序将完全正常运行。

如果我使用:System.setProperty("http.proxyHost", "127.0.0.1");而不是:System.setProperty("http.proxyHost", "localhost");,它可以运行fiddler应用程序运行,无论是上限/非捕获模式,还是没有捕获的流量。

有没有人能够用fiddler捕获他们自己的https流量,而不是通过网络浏览器,而是通过java程序?什么是jvm参数,你如何设置它来做到这一点?感谢

4 个答案:

答案 0 :(得分:96)

创建包含Fiddler证书的密钥库。 使用此密钥库作为JVM的信任库以及代理设置。

以下是如何做到这一点:

  • 导出Fiddler的根证书
  

工具 - >提琴手选项...... - > HTTPS - >将根证书导出到桌面

  • 使用此证书创建密钥库
  

以管理员身份打开命令行(否则keytool不起作用)

     

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

出现提示时输入密码。这应该创建一个名为FiddlerKeystore的文件。

  • 现在以Fiddler作为代理启动JVM,将此密钥库作为信任库启动。你需要这些vmargs:
  

-DproxySet =真

     

-DproxyHost = 127.0.0.1

     

-DproxyPort = 8888

     

-Djavax.net.ssl.trustStore = LT;路径\到\ FiddlerKeystore>

     

-Djavax.net.ssl.trustStorePassword =< Keystore密码>

在你的eclipse运行配置中使用这些vmargs,你应该很高兴。

我能够捕获从JVM发出的HTTPS请求,而不会出现任何问题。

答案 1 :(得分:4)

创建一个包含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 :(得分:4)

您还可以将fiddler密钥导入java可信证书库:

  1. 导出Fiddler的根证书

    工具 - &gt;提琴手选项...... - &gt; HTTPS - &gt;行动 - &gt;将根证书导出到桌面

  2. 以管理员身份运行:

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

    此外,我还遇到了使用Fiddler解密Google API客户端的https流量的问题。 问题是默认情况下它使用它自己的证书存储:

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

    这就是我解决这个问题的方法:

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

答案 3 :(得分:2)

我发现我还需要以下java命令行选项

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