如何在java中使用fiddler捕获https

如何在java中使用fiddler捕获https,java,eclipse,https,fiddler,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 a

我正在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在捕获和未捕获时都在运行,则会产生以下异常:

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处于捕获模式下打开时也是如此,但仍然没有从fiddler捕获任何内容

然后,如果我通过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应用程序运行时运行良好,既有cap-/非捕获模式,也没有捕获的流量


有没有人能够通过fiddler捕获自己的https流量,不是通过web浏览器,而是通过java程序?jvm参数是什么,如何设置它来实现这一点?谢谢

创建一个包含Fiddler证书的密钥库。 将此密钥库与代理设置一起用作JVM的信任库

以下是如何做到这一点:

  • 导出Fiddler的根证书
工具->小提琴手选项…->HTTPS->将根证书导出到桌面

  • 使用此证书创建密钥库
以管理员身份打开命令行(否则keytool不起作用)

\bin\keytool.exe-import-文件C:\Users\\Desktop\FiddlerRoot.cer-密钥库FiddlerKeystore-别名Fiddler

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

  • 现在启动JVM,使用Fiddler作为代理,这个密钥库作为信任库。您将需要这些vmargs:
-DproxySet=真

-DproxyHost=127.0.0.1

-DproxyPort=8888

-Djavax.net.ssl.trustStore=

-Djavax.net.ssl.trustStorePassword=

在eclipse运行配置中使用这些vmarg,您应该可以很好地运行了


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

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

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

创建包含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
更新:

如果您使用的是Apache HttpClient 4.5.5或更新版本,则需要这样做:

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

您还可以将Fiddler密钥导入Java trusted certificates store(只要您知道这是不安全的,并且在任何非开发环境中都不这样做):

  • 从Fiddler内部导出Fiddler的根证书:
  • 工具→ 小提琴手选项。。。→ HTTPS→ 行动→ 将根证书导出到桌面

  • 启动提升的命令提示符,并使用以下命令导入证书。用合适的JDK/JRE版本替换
    jdk1.7.079
    部分。如果安装了多个JDK/JRE,则需要针对每个环境执行此操作
  • 我还遇到了使用GoogleAPI客户端结合Fiddler解密HTTPS流量的问题。问题在于,默认情况下,客户端使用自己的证书存储:

    InputStream keystrestream=GoogleUtils.class.getResourceAsStream(“google.jks”);
    loadKeyStore(certTrustStore,Keystream,“notasecret”);
    
    我就是这样解决的:

    HttpTransport-transport=new-NetHttpTransport()
    //而不是transport=GoogleNetHttpTransport.newTrustedTransport();
    
    您尚未设置ssl提供程序、密钥库、信任库等检查此指南:我也开始使用这些vmarg,但后来意识到它们是多余的。i、 没有它们,我就可以很好地捕获,而仅仅使用这两个参数,而不是proxyPort和proxyHost参数,是行不通的。不确定它是否依赖于虚拟机/环境--编辑--顺便说一句,我是从Windows7上的OracleJDK6捕获的。我就是这样做的。非常感谢:)此解决方案还可以通过使用
    System.setProperty(,)工作而不是
    -D=
    。谢谢。使用Fiddler 5,导出根证书:工具->Fiddler选项…->HTTPS->Actions->Export Root Certificate to DesktopIm开发webapp并使用jboss/wildfly 18作为appserver。我尝试了这个方法和其他一些类似的方法来让fiddler工作,但没有成功。。“找不到请求目标的有效认证路径”您的解决方案应该适用于所有java应用程序,对吗?
    HttpHost proxy = new HttpHost("localhost", 8888, "http");
    DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
    CloseableHttpClient httpclient = HttpClients.custom()
                    .setRoutePlanner(routePlanner)
                    .build();
    
    "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