在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请求进行抓包

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • docker离线安装部署_docker官方中文文档

    docker离线安装部署_docker官方中文文档离线安装docker

    2022年9月26日
    0
  • .NET程序的编译和运行

    程序的编译和运行,总得来说大体是:首先写好的程序是源代码,然后编译器编译为本地机器语言,最后在本地操作系统运行。下图为传统代码编译运行过程:.NET的编译和运行过程与之类似,首先编写好的源代码,然

    2021年12月22日
    52
  • js倒计时跳转页面_什么代码可以实现网页的跳转

    js倒计时跳转页面_什么代码可以实现网页的跳转以下是倒计时120秒跳转代码,对于需要倒计时的页面非常实用,如果倒计时后不想跳转,可以注销掉location.href=这行代码<spanclass=”time”></span><script>vart=120;vartime=document.getElementsByClassName(“time”)[0];functionfun(){t–;time.innerHTML=t;if(t<=0

    2022年8月12日
    3
  • MNIST是什么(plist是什么意思)

    初始的迷茫我想很多菜鸟和我一样,开始零基础学习机器学习,没办法火啊,为了钱大家都是冲呀。估计很多人开始学习ML,就一头雾水,完全不知道在说什么。因为学习模式和学习其他语言完全不同,我们知道学习其他语言的时候,第一个程序就是打印“HelloWorld”。其实机器学习是在某个框架下,使用某种语言,来解决问题。因此对于零基础的菜鸟而言,我们需要先学习好某种语言,可以推荐Python,因为功能强…

    2022年4月17日
    74
  • eclipse code templates

    eclipse code templates

    2021年5月9日
    145
  • 虚拟机配置opc服务器,组态王怎么配置成opc服务器

    虚拟机配置opc服务器,组态王怎么配置成opc服务器组态王怎么配置成opc服务器内容精选换一换您可以在添加监听器时配置健康检查。通常,使用默认的健康检查配置即可。以下操作步骤以共享型负载均衡健康检查配置为例。健康检查与ELB的后端协议是两个相互独立的能力,所以健康检查协议可以与ELB的后端协议相同,也可以不同。为了减少后端服务器的CPU占用,建议您使用TCP协议做健康检查。如果您希望使用HTTP健康检查协议,建议使用HTTP+静态CHNet-FX…

    2022年6月20日
    25

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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