解决Fiddler在抓取https数据包时Tunnel to 443的问题的方法

首先要排除的设置fiddler的问题,可以参考下面的教程去设置fiddler

https://www.cnblogs.com/111testing/p/6436226.html

若是已经排除上面的问题,手机上提示错误信息:java.security.cert.CertPathValidatorException: Trust anchor for certification path not found。而在fiddler提示:A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below,host提示Tunnel to 443,那么这时候就应该是抓包的时候接口缺少SSL的双向验证,我们这时app就需要使用bks证书校验服务端证书,具体实现的方案如下:

1、下面的工具类包含了https的验证和授权验证的方法,直接复制创建即可

public class HttpsUtils {

    public static class SSLParams {
        public SSLSocketFactory sSLSocketFactory;
        public X509TrustManager trustManager;
    }

    public static SSLParams getSslSocketFactory() {
        return getSslSocketFactoryBase(null, null, null);
    }

    /**
     * https单向认证
     * 可以额外配置信任服务端的证书策略,否则默认是按CA证书去验证的,若不是CA可信任的证书,则无法通过验证
     */
    public static SSLParams getSslSocketFactory(X509TrustManager trustManager) {
        return getSslSocketFactoryBase(trustManager, null, null);
    }

    /**
     * https单向认证
     * 用含有服务端公钥的证书校验服务端证书
     */
    public static SSLParams getSslSocketFactory(InputStream... certificates) {
        return getSslSocketFactoryBase(null, null, null, certificates);
    }

    /**
     * https双向认证
     * bksFile 和 password -> 客户端使用bks证书校验服务端证书
     * certificates -> 用含有服务端公钥的证书校验服务端证书
     */
    public static SSLParams getSslSocketFactory(InputStream bksFile, String password, InputStream... certificates) {
        return getSslSocketFactoryBase(null, bksFile, password, certificates);
    }

    /**
     * https双向认证
     * bksFile 和 password -> 客户端使用bks证书校验服务端证书
     * X509TrustManager -> 如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可
     */
    public static SSLParams getSslSocketFactory(InputStream bksFile, String password, X509TrustManager trustManager) {
        return getSslSocketFactoryBase(trustManager, bksFile, password);
    }

    private static SSLParams getSslSocketFactoryBase(X509TrustManager trustManager, InputStream bksFile, String password, InputStream... certificates) {
        SSLParams sslParams = new SSLParams();
        try {
            KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
            TrustManager[] trustManagers = prepareTrustManager(certificates);
            X509TrustManager manager;
            if (trustManager != null) {
                //优先使用用户自定义的TrustManager
                manager = trustManager;
            } else if (trustManagers != null) {
                //然后使用默认的TrustManager
                manager = chooseTrustManager(trustManagers);
            } else {
                //否则使用不安全的TrustManager
                manager = UnSafeTrustManager;
            }
            // 创建TLS类型的SSLContext对象, that uses our TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            // 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书
            // 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书
            sslContext.init(keyManagers, new TrustManager[]{manager}, null);
            // 通过sslContext获取SSLSocketFactory对象
            sslParams.sSLSocketFactory = sslContext.getSocketFactory();
            sslParams.trustManager = manager;
            return sslParams;
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        } catch (KeyManagementException e) {
            throw new AssertionError(e);
        }
    }

    private static KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
        try {
            if (bksFile == null || password == null) return null;
            KeyStore clientKeyStore = KeyStore.getInstance("BKS");
            clientKeyStore.load(bksFile, password.toCharArray());
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientKeyStore, password.toCharArray());
            return kmf.getKeyManagers();
        } catch (Exception e) {
            OkLogger.printStackTrace(e);
        }
        return null;
    }

    private static TrustManager[] prepareTrustManager(InputStream... certificates) {
        if (certificates == null || certificates.length <= 0) return null;
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            // 创建一个默认类型的KeyStore,存储我们信任的证书
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certStream : certificates) {
                String certificateAlias = Integer.toString(index++);
                // 证书工厂根据证书文件的流生成证书 cert
                Certificate cert = certificateFactory.generateCertificate(certStream);
                // 将 cert 作为可信证书放入到keyStore中
                keyStore.setCertificateEntry(certificateAlias, cert);
                try {
                    if (certStream != null) certStream.close();
                } catch (IOException e) {
                    OkLogger.printStackTrace(e);
                }
            }
            //我们创建一个默认类型的TrustManagerFactory
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            //用我们之前的keyStore实例初始化TrustManagerFactory,这样tmf就会信任keyStore中的证书
            tmf.init(keyStore);
            //通过tmf获取TrustManager数组,TrustManager也会信任keyStore中的证书
            return tmf.getTrustManagers();
        } catch (Exception e) {
            OkLogger.printStackTrace(e);
        }
        return null;
    }

    private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
        for (TrustManager trustManager : trustManagers) {
            if (trustManager instanceof X509TrustManager) {
                return (X509TrustManager) trustManager;
            }
        }
        return null;
    }

    /**
     * 为了解决客户端不信任服务器数字证书的问题,网络上大部分的解决方案都是让客户端不对证书做任何检查,
     * 这是一种有很大安全漏洞的办法
     */
    public static X509TrustManager UnSafeTrustManager = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }
    };

    /**
     * 此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,
     * 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。
     * 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true
     */
    public static HostnameVerifier UnSafeHostnameVerifier = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
}

2、一般我们网路请求都是使用okhttp或者底层基于okhttp的框架来请求网络,直接设置OkHttpClient相应sslSocketFactory和trustMananger,类似代码如下

 OkHttpClient.Builder builder = new OkHttpClient.Builder();

                    builder.addInterceptor(new HeaderInterceptor())
                            .addInterceptor(new ParamsIntercepter());
                    HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
                    if (debug) {
                        LoggingInterceptor interceptor =   new LoggingInterceptor.Builder()
                                .setLevel(Level.BODY)
                                .build();
                        builder.addInterceptor(interceptor);

                    }
                    mClient = builder
                            .connectTimeout(30, TimeUnit.SECONDS)
                            .readTimeout(30, TimeUnit.SECONDS)
                     .sslSocketFactory(sslParams1.sSLSocketFactory,sslParams1.trustManager)
                            .build();

然后就可以快乐的抓包了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
### 回答1: Fiddler是一款用于抓包和分析网络流量的工具。如果您想要在Fiddler中使用HTTPS协议进行抓包分析,则需要对Fiddler进行一些配置,使其能够与目标网站建立加密连接。 其中一个常见的问题Fiddler无法通过隧道连接到443端口。这通常是由于系统代理设置的问题导致的。要解决这个问题,您可以尝试以下方法: 1. 在Fiddler中打开“Tools”菜单,选择“Options”,然后选择“Connections”选项卡。在该选项卡中,取消选中“Act as system proxy on startup”复选框。 2. 禁用或修改系统代理设置。在Windows操作系统中,您可以在“Internet选项”中找到代理设置,然后将其禁用或将代理地址和端口修改为与Fiddler相同的地址和端口。 3. 如果您使用的是HTTPS代理,请确保您已经安装了Fiddler的根证书。在Fiddler中,可以通过打开“Tools”菜单,选择“Options”,然后选择“HTTPS”选项卡来找到根证书的安装方法。 希望这些方法可以帮助您解决Fiddler隧道连接443端口的问题。 ### 回答2: 文本中提到“fiddler tunnel to 443 问题”,该问题是指在使用Fiddler抓包,需要将端口号修改为443才能正常捕获HTTPS请求的问题。这个问题是由于HTTPS请求使用加密传输,而Fiddler默认只能捕获HTTP请求,因此需要通过修改端口号的方式来实现HTTPS请求的抓包。 首先,需要在Fiddler的“Tools”菜单下选择“Fiddler Options”,进入设置页面。在“HTTPS”选项卡下,勾选“Decrypt HTTPS traffic”选项,并点击“Export Root Certificate to Desktop”按钮,将证书导出到桌面以便之后的安装。 接着,需要将证书安装到本地信任证书库中。在Windows系统中,可以通过双击证书文件并按照提示操作来实现。安装成功后,需要重启Fiddler,并在“Tools”菜单下选择“Options”菜单中的“HTTPS”选项卡,勾选“Capture HTTPS CONNECTs”选项。 最后,需要在Fiddler的“Rules”菜单下选择“Customize Rules”,并添加以下代码: static function OnBeforeRequest(oSession: Session) { if (oSession.isHTTPS && oSession.uriContains("yourdomain.com")) { oSession["x-overrideHost"] = "yourdomain.com:443"; } } 这段代码的作用是将指定的域名的端口号改为443,以便Fiddler能够正常捕获HTTPS请求。在添加完上述代码后,保存并重启Fiddler即可。 总之,“fiddler tunnel to 443 问题”可以通过上述方法解决,从而实现对HTTPS请求的抓包。同需要注意的是,由于HTTPS请求使用加密传输,因此在抓包需要遵循相关法规和道德规范,切勿用于非法用途。 ### 回答3: Fiddler是一款广泛使用的抓包工具,可以用于监视HTTP请求和响应。有候,我们需要在Fiddler上捕获加密的HTTPS流量,这就需要使用Fiddlertunneling(隧道)功能。 默认情况下,在Fiddler上不能直接抓取HTTPS流量。Fiddler使用的是自己生成的根证书来代理HTTPS流量,但大多数浏览器都不信任这个根证书,因此浏览器会提示安全警告。为了解决这个问题Fiddler提供了一个tunneling(隧道)功能,用于将HTTPS流量通过HTTPS隧道转发到Fiddler中,从而避免了浏览器检测证书的问题。 在Fiddler中,打开Tools->Options,选择HTTPS选项卡,勾选"Decrypt HTTPS traffic"和"Ignore server certificate errors"选项,然后单击"Actions"按钮,选择"Export root certificate to desktop",将证书保存到桌面。接下来,需要将该根证书导入到操作系统的受信任根证书颁发机构中,以便浏览器可以信任它。然后,重启Fiddler,选择"Rules"选项卡,打开Customize rules文件,在OnBeforeRequest函数中添加以下代码: if (oSession.HTTPMethodIs("CONNECT") && oSession.HostnameIs("localhost:443")) { oSession["x-replywithtunnel"] = "FakeTunnel"; return; } 保存并重新加载Customize rules文件,Fiddler就可以开始抓取HTTPS流量了。 总之,使用Fiddlertunneling(隧道)功能,可以轻松捕获HTTPS流量,从而帮助我们分析和调试网站的安全性及性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值