在Android手机上对https请求进行抓包

在Android手机上对https请求进行抓包前段时间跟QQ群里的群友聊天时无意聊到了抓包的话题。抓包可以说是程序员日常开发调试问题的一个重要手段,可以帮助我们理清客户端与服务器之间的数据传输问题,以便于甩锅。在过去,网络请求基本都是靠的http协议,那个时候的抓包是一件非常简单的事情。然而这几年,http协议在逐渐被淘汰,几乎所有的网络请求都变成了https协议,这就使事情变得复杂了。群里一位朋友说,https是不可能被抓包的,不然怎么保证https传输的安全性,毕竟那么多大公司都在用这个协议来传输重要的数据。这其实是一个比较有意思的话题

大家好,又见面了,我是你们的朋友全栈君。

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。

前段时间跟QQ群里的群友聊天时无意聊到了抓包的话题。抓包可以说是程序员日常开发调试问题的一个重要手段,可以帮助我们理清客户端与服务器之间的数据传输问题,以便于甩锅。

在过去,网络请求基本都是靠的http协议,那个时候的抓包是一件非常简单的事情。然而这几年,http协议在逐渐被淘汰,几乎所有的网络请求都变成了https协议,这就使事情变得复杂了。

群里一位朋友说,https是不可能被抓包的,不然怎么保证https传输的安全性,毕竟那么多大公司都在用这个协议来传输重要的数据。

这其实是一个比较有意思的话题,https确实是非常安全的。但同时,https也确实是可以抓包的,它们两者之间并不冲突。

考虑到仍然有许多朋友在这方面还有些不太了解,我准备写两篇文章来讲讲https抓包的相关知识。本篇文章先讲实践,教大家如何在Android手机上对https请求进行抓包。下一篇文章会讲原理,我们一起解析一下,为什么如此安全的https协议却仍然可以被抓包呢?

那么先从实践看起吧。

抓包工具的使用

要对网络请求进行抓包,首先肯定要选择一个抓包工具才行。

专业的抓包工具有很多,根据我的观察,国内的大多数开发者都比较喜欢用Charles这个工具来进行抓包。不过我个人更喜欢用Fiddler这个工具,而且我们平时工作时如果要进行抓包也都是用的Fiddler。因为Fiddler和微软内部的日志分析工具是相互兼容的,并且Fiddler的作者也在微软工作。

那么本篇文章我都会以Fiddler这个工具来进行举例讲解,当然如果你习惯用Charles也完全没有问题,只是在工具的操作上可能会有所区别,原理是完全相同的。

首先需要在你的电脑上安装Fiddler,这个工具是完全免费的,下载地址是:

https://www.telerik.com/fiddler/fiddler-everywhere

安装完成之后登录一下就可以使用了,它会自动抓取你当前这台电脑上的所有网络请求包。

但是如果我们想要抓取手机上的网络请求,那么还需要做点额外的配置才行。

首先从Fiddler顶部工具栏依次点击View -> Preferences -> Connections,将会看到如下所示界面:

在Android手机上对https请求进行抓包
这里有两点需要注意,一个是端口号,默认值是8866,如果没有什么特殊需求的话可以不用修改。

第二个是Allow remote computers to connect这个选项是一定要勾上的,不然手机上的网络请求将无法抓到。

勾上第二个选项,点击SAVE,这样电脑端的配置就完成了。

接下来我们还需要在手机端进行一些简单的配置。

要确保的是,你的手机和用于抓包的这台电脑必须在同一个局域网下。

然后修改手机当前连接Wifi的高级选项,将代理类型改为手动,将代理主机名改成电脑的ip地址,将代理端口改成8866,如下图所示:


在Android手机上对https请求进行抓包

点击保存即可。

完成以上配置之后,其实我们就可以使用Fiddler来对手机上的网络请求进行抓包了。不信你可以试一试在手机的浏览器上访问以下地址:

http://guolin.tech/api/china/

应该会看到如下界面:


在Android手机上对https请求进行抓包

然后再到Fiddler中查看一下,你就能发现刚才手机上的网络请求包已经成功被Fiddler抓到了(有时Fiddler中显示的包信息过多,不方便查看,可以使用Ctrl+X清空信息):
在Android手机上对https请求进行抓包
可以看到,这条网络请求的所有细节在Fiddler中一览无余,包括请求的头信息,响应的头信息,响应的body内容等等。

抓包工具将网络通讯的背后细节全部搬到了台面上,这样当客户端和服务器遇到联调问题时,到底是客户端的锅还是服务器的锅,看一看抓出来的包就全部清楚了。

以上就是抓包工具最传统的用法,然而这种用法现在已经不那么好使了,因为还在使用http协议的网络请求已经越来越少,绝大部分的网络请求都变成了https协议。

对https请求进行抓包

https协议是一种加密传输的网络协议,所传输的数据不再是以明文的方式来传输,而都是加密过后再进行传输的。

这种协议保障了用户的数据安全,但对于抓包而言却是一件苦恼的事情。因为数据都加密了呀,我们抓到的包也都是一些密文信息,所以根本就无法用于定位问题。

比如我们可以尝试在手机浏览器中访问一下必应,然后观看Fiddler中抓到的包信息,如下图所示:
在Android手机上对https请求进行抓包
可以看到,Fiddler虽然能够捕获到访问必应的网络请求,但是却无法解密出具体的传输内容,这种包对于我们分析问题并没有任何帮助。

那么对于https请求的网络包我们到底要怎么抓呢?别担心,Fiddler是支持这个功能的,下面跟着我一步步操作就行。

首先需要在Fiddler中开启https抓包功能,从Fiddler顶部工具栏依次点击View -> Preferences -> HTTPS。

在HTTPS设置页面中,先点击Trust root certificate来安装证书,然后勾选Capture HTTPS traffic选项,如下图所示:
在Android手机上对https请求进行抓包
点击SAVE保存,这样你就可以抓到电脑上https请求的包了。

但是手机上https请求的包我们还是抓不到的,你可以试试再次在手机上访问必应,将会看到如下界面:


在Android手机上对https请求进行抓包

出现这种错误基本都是证书的原因导致的,在下篇文章中我会详细分析这个错误出现的原因,本篇文章中我们先将它解决就好了。

在你的手机浏览器中访问如下地址:

http://ipv4.fiddler:8866/

将会看到一个由Fiddler内置的网页:


在Android手机上对https请求进行抓包

点击FiddlerRoot certificate这个链接,下载并安装由Fiddler提供的手机证书。

安装完成之后再次访问必应,你就会发现不会再报错了,而是可以正常显示出网页的内容:


在Android手机上对https请求进行抓包

然后观察Fiddler,可以看到,请求必应首页的网络包也被成功抓到了,而且这次不再是密文,而是解密后的数据:
在Android手机上对https请求进行抓包
对https请求的抓包问题,就这样解决了!

对Android应用进行抓包

如此看来,https抓包貌似也并不是一件难事。

没错,但还有一个细节需要大家注意。上述方案只适用于对浏览器中的网络请求进行抓包,如果你是想要对其他应用程序的网络请求抓包的话,仍然还是抓不到的。

为了证实这一点,我们就来新建一个应用程序,并编写一段最简单的网络请求代码,看看到底能不能抓到它发出的网络请求。

整个程序非常简单,我们在MainActivity中加入一个按钮,当点击按钮时就发起一个网络请求,代码如下所示:

class MainActivity : AppCompatActivity() { 
   

    override fun onCreate(savedInstanceState: Bundle?) { 
   
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val button: Button = findViewById(R.id.button)
        button.setOnClickListener { 
   
        	sendRequest()
        }
    }

    private fun sendRequest() { 
   
        thread { 
   
            var connection: HttpURLConnection? = null
            try { 
   
                val response = StringBuilder()
                val url = URL("https://www.bing.com")
                connection = url.openConnection() as HttpURLConnection
                val input = connection.inputStream
                val reader = BufferedReader(InputStreamReader(input))
                reader.use { 
   
                    reader.forEachLine { 
   
                        response.append(it)
                    }
                }
                Log.d("TAG", response.toString())
            } catch (e: Exception) { 
   
                e.printStackTrace()
            } finally { 
   
                connection?.disconnect()
            }
        }
    }

}

没错,总共就这么多代码。但是不要忘记我们还得在AndroidManifest.xml中声明网络权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.capturetest">

    <uses-permission android:name="android.permission.INTERNET" />
    ...

</manifest>

好了,现在来运行一下程序看一看效果吧。点击界面上的按钮,会向必应主页发起一条网络请求,然后观察Fiddler中的数据包:
在Android手机上对https请求进行抓包
可以看到,我们是无法像之前在浏览器中那样,成功抓到并解析出https请求的包信息的。

为什么会这样呢?这是因为Android在7.0系统中进行了一项安全升级。从Android 7.0系统开始,只是在手机上安装了抓包工具的证书,仍然是无法对https请求进行抓包的,还必须要在应用程序的代码中加入一段网络安全配置才行。

这项升级使得每个应用程序都变得更加安全,因为对https抓包确实是一个比较危险的行为,所有加密传输的数据都以明文的形式展示出来了。当然,如果是为了调试程序而抓包,这算是一个正当理由,但是你也理应只能对自己的程序进行抓包调试而已。如果只要在手机上安装了证书就可以对所有App的https请求进行抓包,那么无疑大大降低了这些App的安全性。

因此,Android 7.0系统中才做了这项安全升级。默认情况下,我们无法对各个App的https请求进行抓包,如果你是想要对自己App的https请求抓包的话,那么可以这样做。

在res/xml目录下创建一个network_security_config.xml文件,然后加入如下配置:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="user"/>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
</network-security-config>

接下来还需要在AndroidManifest.xml中配置android:networkSecurityConfig属性来让上述配置生效:

<application ... android:networkSecurityConfig="@xml/network_security_config">
    ...
</application>

这样我们就可以对当前的应用程序发出的https网络请求进行抓包了。

重新运行一下程序,让我们再来试试吧,结果如下图所示:
在Android手机上对https请求进行抓包
结果正如我们预期的那样工作了。

最后一个小疑惑

那么本篇文章的内容到这里就差不多该结束了。

但是不知道大家有没有产生一个小疑惑,既然是从Android 7.0开始必须要在自己的应用程序中加入网络安全配置才能对https请求抓包,为什么我们一开始在浏览器中什么都没配,却也成功抓到了https请求的网络包呢?

这个问题其实让我困惑了很久,直到现在加入了微软Edge项目组才终于解开了这个疑惑。

Edge是一款基于Chromium内核的浏览器,Chrome也是,许多主流的浏览器都是。其实答案一直都在Chromium的源码中,只是我之前从来没有勇气去看过。

我们来查看一下Chromium源码中的AndroidManifest.xml文件,部分代码如下图所示:
在Android手机上对https请求进行抓包
可以看到,Chromium的源码中也加入了一段android:networkSecurityConfig配置,那么我们继续跟进去看看里面到底配置了什么:
在Android手机上对https请求进行抓包
这不是和我们刚才在Demo中配置的内容一模一样吗?

自此真相大白了,原来之所以浏览器不需要做额外的配置也能对https请求进行抓包,是因为Chromium源码中已经对此做好了配置,而所有基于Chromium内核的浏览器也就都自动拥有了这个功能。

如果你想要在线查看Chromium的源码,可以访问这个地址:

https://source.chromium.org/

好了,本篇文章的内容就到这里。相信看完这篇文章,会对大家平时的网络开发与调试工作产生一定的帮助。

解决了怎么用的问题,接下来就要去了解原理了。下篇文章中我们来一起探讨一下为什么传说中如此安全的https协议却仍然可以被抓包呢?点击这里继续阅读下篇文章

另外,如果想要学习Kotlin和最新的Android知识,可以参考我的新书 《第一行代码 第3版》点击此处查看详情

关注我的技术公众号,每个工作日都有优质技术文章推送。

微信扫一扫下方二维码即可关注:

在Android手机上对https请求进行抓包

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/149038.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • centos7 防火墙开放svn通过

    centos7 防火墙开放svn通过

  • hibernate官方新手教程 (转载)

    hibernate官方新手教程 (转载)

    2021年12月30日
  • bindService与startService区别

    bindService与startService区别1.StartedService中使用startService()方法来进行方法的调用,调用者和服务之间没有联系,即使调用者退出了,服务依然在进行【onCreate()->onStart

  • php递归算法经典实例_递归算法的步骤

    php递归算法经典实例_递归算法的步骤递归算法对于任何一个编程人员来说,应该都不陌生。因为递归这个概念,无论是在PHP语言还是Java等其他编程语言中,都是大多数算法的灵魂。对于PHP新手来说,递归算法的实现原理可能不容易理解。但是只要你了解掌握了这个算法原理,就可以灵活运用递归算法实现编程中的多种功能比如实现无限分类等。递归也是入门者最需要掌握的一个基础算法技巧。下面郑州网站建设公司燚轩科技就通过具体代码示例为大家介绍PHP递归算法…

  • STM32中文参考手册_haar小波分解

    STM32中文参考手册_haar小波分解注:本文是程序的说明和实现思路,代码见:https://download.csdn.net/download/hnxyxiaomeng/10301718一、主要思路原始信号:OrgSig信号长度:DWT_SIG_LEN小波分解层数:N与MATLAB类似,小波分解后产生2个数组DWT_L和DWT_C,但定义与MATLAB不同。定义如下:DWT_L:[DWT_SIG_LEN,c…

    2022年10月19日
  • html5 a标签去下划线,css中如何去掉a标签的下划线?[通俗易懂]

    html5 a标签去下划线,css中如何去掉a标签的下划线?[通俗易懂]我们在HTML网页制作过程中,相信大家对css文本超链接这个概念并不陌生。我们都知道想要给某段文本或者指定元素添加一个锚点也就是超链接需要用到HTML中的a标签。那么有的新手可能就会发现,在使用a标签时文本超链接会自动出现下划线!从视觉美观上来说枯燥单调的文本超链接显示显然并不好看。那么该如何去掉a标签的下划线呢?下面我们来看一下css去掉a标签下划线的方法。本篇文章就给大家详细讲讲怎么去掉css…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号