eclipse—如何用java中的fiddler捕获https

0sgqnhkj  于 2021-07-11  发布在  Java
关注(0)|答案(4)|浏览(490)

我正在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参数,如何设置它来实现这一点?谢谢

8qgya5xd

8qgya5xd1#

创建包含fiddler证书的密钥库。将此密钥库与代理设置一起用作jvm的信任库。
下面是如何做到这一点:
导出fiddler的根证书
工具->小提琴手选项…->https->将根证书导出到桌面
使用此证书创建密钥库
以管理员身份打开命令行(否则keytool不起作用)
<jdk\u 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=<path\to\fiddlerkeystore>
-djavax.net.ssl.truststorepassword=
在eclipse运行配置中使用这些vmarg,您就可以开始了。
我能够捕获来自jvm的https请求,而不会出现任何问题。

v7pvogib

v7pvogib2#

创建包含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();
k5ifujac

k5ifujac3#

您还可以将fiddler密钥导入java可信证书存储(只要您知道这是不安全的,并且在任何非开发环境中都不这样做):
从fiddler中导出fiddler的根证书:
工具→ 小提琴手选项。。。→ https协议→ 行动→ 将根证书导出到桌面
启动提升的命令提示符并使用以下命令导入证书。更换 jdk1.7.0_79 使用适当的jdk/jre版本。如果安装了多个jdk/jre,则需要针对每个环境执行此操作。

"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

我在使用googleapi客户端和fiddler组合解密https流量时也遇到了问题。问题是,默认情况下,客户端使用自己的证书存储:

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

我就是这样解决的:

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

u5i3ibmn4#

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

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

相关问题