天天给 App 抓包,还不懂 HTTP 代理吗?

2023-10-31

一、序

今天来和大家一起聊聊 HTTP 代理。

在 HTTP 协议中,最基础的就是请求和响应的报文,而报文又由报文头和报文实体组成。大多数 HTTP 协议的使用场景,都是依赖设置不同的 HTTP 请求/响应 的 Header 来实现的。

既然要说到代理,先提两个问题来当主线,从问题出发讲解 HTTP 代理。

  1. 抓包工具是如何实现 HTTP 抓包的。
  2. 对于 HTTPS 流量,不安装证书的情况下,通过抓包工具,请求和响应依然正常。

今天说的 HTTP 代理,更多的是一种抽象概念,其中的原理才是最关键的。

二、HTTP 代理

2.1 什么 HTTP 代理?

说到 HTTP 代理,作为客户端开发,最熟悉的就是使用 Fiddler、Charles 等工具进行抓包时,需要在手机上挂个代理,来方便我们排查一些网络问题,这只是代理众多使用场景中的一个。

实际上,HTTP 代理(Web 代理)是一种存在于网络中间的实体,可以提供各种功能。如果没有 HTTP 代理,客户终端就要直接与终端服务器进行交互。而有了 HTTP 代理后,客户终端就可以与代理通信,然后由代理代表客户端与服务器进行交互。

HTTP 代理算是最容易理解的一个 HTTP 协议概念,它和我们的生活最贴近。在我们的生活中,存在各种代办的服务。

例如你和女友准备出国游,一些不免签的国家,就需要提前办理签证。我们不熟悉自然觉得流程很复杂,这时就可以选择交由旅行社来代理办理签证,你只需要根据对方提供的清单准备材料,就可以很方便的获得签证。在这个过程中,你节省了时间,而旅行社赚了你一点钱。

img

代理服务,就是代理客户端完成事务处理的中间人,它接管客户端的事务,代替客户端与服务端交互。

代理服务是一个抽象的中间实体,可以存在网络的各个中间点,浏览器、路由器、代理服务器、Web 服务器的反向代理等,

2.2 HTTP 代理的分类

从最熟悉的抓包工具说起,Fiddler、Charles 这种抓包工具,封装的都非常好,哪怕我们完全不理解 HTTP 代理的细节,简单配置就可以使用。

在使用过程中,你会发现两种场景:

  1. 对于 HTTP 协议请求,可以直接显示请求/响应报文的细节
  2. 对于 HTTPS ,如果没有导入证书,请求依然可以发送至服务器,并且也可以正常返回数据,但是不会显示报文细节。

在没有导入证书的情况下,HTTPS 请求我们无法获知细节,但是并不影响我们的请求和响应。

这个两种不同的表现,也对应了两种不同的 HTTP 代理:

  1. 普通代理。基于修订后的 RFC 2616 在 HTTP/1.1 中被定义。这种代理扮演的是「中间人」的角色。对客户端来说,它是服务端,而对真正的服务端来说,它又是客户端,它就是负责在两端之间传递 HTTP 报文。
  2. 隧道代理。这种一种基于 TCP 协议的隧道传输代理,它通过 HTTP 协议的 CONNECT 方法完成通信,以 HTTP 的方式,实现任意基于 TCP 的应用层协议代理。

接下来我们就分别对这两种代理进行讲解。

2.3 普通代理

普通代理,理解起来并不复杂,它是网络中的中间实体,位于客户端和服务端之间,扮演「中间人」的角色,在两端之间来回传递报文。

这个「中间人」左手牵着客户端,右手牵着服务端,在收到客户端发送的请求报文时,需要正确的处理请求和连接状态,同时向服务器发送新的请求,在收到响应后,将响应结果包装成一个响应体返回给客户端。

img

在普通代理的流程中,代理两端都是有可能察觉不到「中间人」的存在。

举个例子,我们要访问 A 网站,实际上我们是向代理服务器发送请求,而代理服务器又再向 A 网站发起请求,最终将响应体通过代理服务器,返回给我们。在我们的角度,我们正常的向一个网站服务器发起请求,并且对方也返回给我们正确的数据,在这个过程中,我作为客户端,会认为代理服务器就是 A 网站的服务器,而 A 网站的服务器,又认为代理服务器是一个真实的用户。

这里说到,代理服务器作为「中间人」是可以隐藏自己的存在,但是如果我们作为一个“守规矩”的代理服务器,想要将客户端的 IP 传递给服务端,可以通过 X-Forwarded-IP 这个自定义的 Header,来告诉服务端真正的客户端 IP 地址。

HTTP 协议作为一种松散的协议,服务器在接收到 X-Forwarded-IP 这个请求头时,是无法验证其真伪的。它可能是代理服务器伪造的,也可能是真实的。所以服务端从 HTTP 头部获取 IP 时,就需要格外小心。

普通代理很好理解,但是它也有缺陷,它只适用于 HTTP 协议。

在普通代理模式下,所有请求响应的数据,对于代理这个「中间人」来说,都是透明并且可以任意操作,这就会带来各种数据安全的隐患。

说到网络数据安全,首先想到的就是 HTTPS,但是 HTTPS 这种证书认证的机制,又是中间人劫持的克星。

严格上来说,HTTPS 下不存在中间人攻击,除非是人为的犯错了,没有对证书严格校验,或者证书被泄露。

在普通的 HTTPS 请求中,服务端不验证客户端的证书,中间人可以作为客户端与服务端完成 TLS 握手。

但是由于代理中间人没有证书密钥,也就无法伪造服务端和客户端简历的 TLS 连接,这会导致请求失败。

这个场景,对标到抓包工具的工作流程中,你会发现,如果想用 Charles(或Fiddler) 抓 HTTPS 的网络数据包,就需要在手机上安装一个 Charles 的 CA 证书,让手机设备信任此证书,才可以完成抓包,此时走的就是普通代理的模式。

那换个角度,假如在手机上没有安装 Charles 提供的证书,也并没有影响到请求和响应,Charles 只是无法解密 HTTPS 数据,这是如何做到的呢?

这就需要用到隧道代理

2.4 隧道代理

隧道代理,又称为 Web 隧道(Web tunnel),这种方式可以通过 HTTP 连接发送非 HTTP 流量,这样可以在 HTTP 上捎带其他协议的数据。

隧道代理是利用 HTTP 的 CONNECT 方法建立起来的。CONNECT 方法,最初并不是 HTTP/1.1 的核心规范,但却是一种得到广泛使用的扩展,它在 2014 年发布的 HTTP/1.1 修订版中,才对 CONNECT 及隧道代理有了清晰的描述。

HTTP 隧道代理的工作流程是什么样的?

一次普通的 HTTP 请求,Header 部分以连续的两组 CRLF(\r\n)作为结束标记,如果后面还有内容,就是 Content 部分的内容,也称为请求/响应体(Content),如果存在 Content 内容,就需要在 Header 中增加 Content-Length 来标记 Content 部分的长度。接收方(服务端)会根据这个长度来读取数据。

CONNECT 报文的请求,是没有 Content 部分的,只有 Request-Line 和 Header,他们仅供代理服务器使用,并不会传递给终端服务器。请求的 Header 部分一旦结束(两组连续的 CRLF),后面的所有数据,都被视为应该转发给终端服务器的数据,代理需要把他们无脑的直接转发,并且不限制长度,直到从客户端的 TCP 读通道关闭。

CONNECT 的响应报文,在代理服务器和终端服务器建立连接后,可以向客户端返回一个 200 Connect established 的状态码,以此表示和终端服务器的连接,建立成功。这个 200 Connect established 的 Header 部分一旦结束(两组连续的 CRLF),后面所有的数据均为远端服务器返回的数据,同理,代理服务器会直接转发终端服务器的数据给客户端,直到终端服务器的 TCP 读通道关闭。

img

了解清楚 HTTP 隧道的工作流程之后,就知道 CONNECT 方法请求隧道网管创建一条到达任意目的服务器和端口的 TCP 连接,并对客户端和服务端之间的后续数据,进行无脑的盲转发

通过隧道代理,代理服务器不再作为中间人,不再需要改写浏览器的请求,而是把浏览器和终端服务器的数据,原样转发,这样浏览器就可以直接和终端服务器进行 TLS 握手,并传输加密的数据。

2.4 导入证书后,Charles 抓 HTTPS 流程

Charles 作为抓包工具,在手机上没有导入证书的时候,是通过隧道代理来保证数据的传输。一旦导入证书之后,Charles 就又切换到普通代理的工作模式,此时我们就可以解析 HTTPS 的流量数据。

这里简单说一下原理。

在导入证书后,请求时手机就会信任 Charles 伪造的证书,而 Charles 又伪装成真实的客户端与服务端之间建立正确的 TLS 连接。此时,Charles 作为「中间人」,两端的 TLS 流量都是可以被解密的。

三、总结时刻

到这里就了解清楚 HTTP 代理的细节,其实很抽象的概念,也很好理解。

简单来说,HTTP 代理可以分为两类,普通代理和隧道代理。

普通代理作为「中间人」存在,在一次请求中,客户端明文请求代理服务器,在收到请求后,代理服务器又明文去请求终端服务器。在这整个过程中,数据都是明文传输,中间人可以对其中传递的数据进行改写,这就是著名的中间人攻击,可见其有多不安全。

这就引申出了支持 HTTPS 的隧道代理,此时代理服务器就不再作为中间人,无法改写客户端的请求,而仅仅是在建立连接后,将客户端的请求,通过建立好的隧道,无脑的转发给终端服务器。

关于 HTTP 代理的细节就到这里,有任何问题欢迎留言讨论!

更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》

1.Android车载应用开发系统学习指南(附项目实战)

2.Android Framework学习指南,助力成为系统级开发高手

3.2023最新Android中高级面试题汇总+解析,告别零offer

4.企业级Android音视频开发学习路线+项目实战(附源码)

5.Android Jetpack从入门到精通,构建高质量UI界面

6.Flutter技术解析与实战,跨平台首要之选

7.Kotlin从入门到实战,全方面提升架构基础

8.高级Android插件化与组件化(含实战教程和源码)

9.Android 性能优化实战+360°全方面性能调优

10.Android零基础入门到精通,高手进阶之路

敲代码不易,关注一下吧。ღ( ´・ᴗ・` )

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

天天给 App 抓包,还不懂 HTTP 代理吗? 的相关文章

  • Android 12:如何防止更改手机壁纸时重新启动活动?

    在 Android 12 上 如果我们开启一个活动 进入手机主屏幕更换壁纸 切换回我们的 Activity 该 Activity 重新启动 看起来它与 Material You 主题有关 我想在我的应用程序进入前台时禁用活动的重新启动 有办
  • Espresso - 检查使用按钮按下意图打开哪个活动?

    是否可以跟踪按下某个按钮后打开了哪个 Activity 我有一个测试 其中当单击 按下按钮时 it 向服务器发送请求 直到发送请求时 它打开一个活动 验证是否执行成功在测试中 我需要检查打开的 Activity 是什么 我的测试示例 检查
  • android - EditText 打字速度很慢

    我的 EditText 在打字时响应速度很慢 这种滞后现象足以让我找到解决方案 我做了一些研究 发现了一个 SO 线程输入文本时 EditText 滞后 https stackoverflow com questions 6173591 a
  • 任务“:app:dexDebug”执行失败

    我目前正在处理我的项目 我决定将我的 Android Studio 更新到新版本 但在我导入项目后 它显示如下错误 Information Gradle tasks app assembleDebug app preBuild UP TO
  • 在 Android 中的活动、服务和应用程序之间传递变量

    有人可以给我提供以下活动 服务 应用程序组合的示例吗 我拥有这三个 但我已经把我的应用程序弄得一团糟 试图在这个地方传递一堆变量 现在我不知道发生了什么 请注意 我是 Android 新手 最近我一直在努力解决这个问题 因为有很多方法可以实
  • Django:如何测试“HttpResponsePermanentRedirect”

    我正在为我的 django 应用程序编写一些测试 在我看来 它使用 HttpResponseRedirect 重定向到其他一些网址 那么我该如何测试呢 姜戈TestCase类有一个方法assertRedirects https docs d
  • android 谷歌+登录定制

    我正在创建一个 Android 应用程序 现在我正在实现社交网络登录 Facebook 按钮很好 但 google 按钮的语言与 Facebook 不同 另外 它只说 登录 我想让它说 用谷歌登录 我是 android 编程的新手 看到我需
  • 无法解析符号 FlutterActivity

    我使用 VCS gt Checkout from Version Control 将 flutter 项目从 github 导入到 Android Studio 中 现在我面临的问题是 Cannot resolve symbol Flutt
  • 如何在照片删除后刷新 Android 的 MediaStore

    问题 如何使媒体存储刷新其已删除文件的条目 从外部存储中删除代码中的照片后 我仍然在图库中看到已删除照片的插槽 空白照片 画廊似乎反映了媒体存储 并且在媒体存储中找到了已删除的照片 直到手机重新启动或通常 直到重新扫描媒体为止 尝试扫描已删
  • HTTPbis - bis 是什么意思?

    我经常看到 bis 附加到协议版本 例如 v 34bis 或 httpbis bis 是什么意思或代表什么 我认识的一位电信工程师认为它可能起源于法国 正如其他人已经说过的 bis 来自 两次 或 重复 http oxforddiction
  • 如何检测 Google Play 上是否有我的应用程序的更新? [复制]

    这个问题在这里已经有答案了 有没有办法以编程方式检查 Google Play 上我的应用程序是否有更新 以便通知用户 我知道 android google play 有自动通知 但我想使用我自己的通知 弹出消息来更新可用性 有点像 Vibe
  • Locale.getDefault().getCountry() 返回空字符串

    我正在尝试使用国家 地区代码获取用户语言 例如en US es es 但是当我使用Locale getDefault getCountry 它返回空字符串 虽然它给了我正确的语言Locale getDefault getLanguage N
  • Android 在启动时启动服务,如何在设备重启后重新启动服务类?

    我需要在启动时启动一项服务 我搜索了很多 他们正在谈论广播接收器 由于我是 Android 开发新手 所以我对 Android 上的服务并没有清楚的了解 请提供一些源代码 您的接收者 public class MyReceiver exte
  • 如何在 Android 上的 HttpPost 中发送 unicode 字符

    我试图在我的应用程序中允许多语言支持 这会发出 HTTP post 来上传新消息 我需要做什么才能支持日语和其他非拉丁语语言 我的代码目前看起来像这样 note the msg string is a JSON message by the
  • 当参数具有默认值时,为什么无法使用导航组件将参数传递给片段?

    我正在使用导航组件 但我不明白为什么如果定义了参数 则将参数传递给下面的方法时会出现错误 我正在使用 SafeArgs 只有当我为此参数定义默认值时才会出现此错误 有人可以解释一下为什么会发生这种情况以及如何解决它吗 这是导航图的部分代码
  • onTouchEvent()中如何区分移动和点击?

    在我的应用程序中 我需要处理移动和单击事件 一次点击是由一个 ACTION DOWN 操作 多个 ACTION MOVE 操作和一个 ACTION UP 操作组成的序列 理论上 如果您收到 ACTION DOWN 事件 然后收到 ACTIO
  • 模拟器:进程已完成,退出代码为 134(被信号 6:SIGABRT 中断)

    我最近刚刚开始在 Mac 上下载 Android Studio 版本 3 0 1 但收到以下错误 模拟器 进程已完成 退出代码为 134 被信号 6 SIGABRT 中断 我按照 Android Studio 教程操作并能够运行模拟器 但在
  • 按名称查找视图

    是否可以通过名称而不是 id 来查找视图 findViewById R id someView 但我想做这样的事情 findViewByName someView 在处理 xml 时 您必须通过标识符查找视图 但是您可以使用以下方式查找标识
  • Android:如何通过右侧的十字按钮清除EditText

    我创建了一个EditText用于搜索 左侧包含搜索图标 右侧包含图标
  • Amazon IAP 不会调用 onPurchaseResponse

    我有一个 Android 应用程序 它使用 IAP 我正在发送PurchasingManager initiateGetUserIdRequest 并得到用户识别成功 in onGetUserIdResponse 得到回复后Purchasi

随机推荐

  • 计算机导论 复习 第二章 神奇的0和1

    一 核心知识点 1 二进制的无符号数 有符号数的 原码 补码 表示规则 2 二进制数的算术运算 逻辑运算规则 3 二进制与十进制 八进制 十六进制数之间的相互转换方法 4 计算机内存 外存以及CPU中寄存器 高速缓存 二 选择题 1 在计算
  • Redis中的排序可以怎么实现?

    遇到这个问题 我上来就回答可以利用数据结构的特性 比如Zset的自带排序 当时没有想到redis也是自带sort功能 对无序数据结构进行后续排序的 先看AI的表现 问题 Redis排序知道吗 如果我的业务场景中需要引入Redis缓存 且需要
  • 遥感影像分类方法

    最初的遥感影像分类是通过目视解译 濮静娟 1984 来完成的 对研究人员的主观意识有较强的依赖性 而且效率较低 适用于数据量较小的情况 通常作为其他方法对比的对象 目前的遥感图像分类主要以计算机分类为主 因此按照人工参与的程度可以将分类方法
  • jenkins系列教程

    jenkins系列教程
  • echarts之横式柱状图

    echarts之横式柱状图 文末有完整代码 可以直接复制使用 效果图 原理 设置x轴为不显示 只显示y轴 设置两个y轴 一个显示柱子 另一个只显示柱子的边框 通过设置两个y轴柱子的层次度 使得看起来像是一个柱子 该实例是在官方例子的基础上修
  • CSS设置滚动条不可见,但可以滚动

    在一个固定窗口内我们做一个可滚动的菜单的时候经常会出现很宽的滚动条 不仅影响美观而且影响布局 解决办法就是在它的外层再套一个div并且设置为overflow heidden 子元素设置overflow y x scroll 并给够足够的宽度
  • 函数指针与指针函数区别

    简述 最近看到安森美芯片的boot的部分代码 如下 写的不易观看 可能C萌新 不易理解 这涉及到指针函数 函数指针的相关概念 typedef enum BOOTROM ERR NONE 0x0 BOOTROM ERR BAD ALIGN 0
  • 频繁FullGc排查思路

    现象 通过监控系统平台告警感知到 某应用某IP在某段时间内出现FullGC FullGC的过程伴随着STW 如果过于频繁 将会导致用户体验极具下降 FullGC的出现经常伴随老年代空间被打满的情况 可以通过监控视图来观测到 当前统一使用CM
  • cs186 学习笔记

    书籍准备利用数据库系统概念 用课程参考资料和题 课程网站 答案 HW0 主要是后面会用到的一些配置 Docker Git Box 课程建议说多备份 Box是本地备份 Git是远程的 都不太会 需要先把这些看完 HW1
  • ubuntu下查看软链接

    工作笔记 以python为例 以root用户进入 usr bin 目录 找到python 可以看到python被链接到python2 7这个执行程序上 建立新的软链接 ln s 源文件 目标文件 删除 rm rf 链接名 转载于 https
  • python求素数

    口求100内的素数 个数能被从2开始到自己的平发根的正整数整数整除 就是合数 import math n 100 for X in range 2 n for i in range 2 math ceil math sqrt x if x
  • 追梦路上—记这一年的自己

    这一年的文字 借这个总结的机会将自己的博客总结 2014年9月 2015年9月 看了一遍 既是在回顾总结 也是在看自己这一年的成长变化 B S系列 牛腩新闻发布系统 只写了一篇关于发布网站和分页的总结 现在回去看 感觉价值不是很大 贴了很详
  • 如何实现小型WEB搜索引擎(C#+SQL Server全文检索+Asp.net)

    1 引言 21世纪 中国互联网搜索引擎领域可谓群雄逐鹿 百度 Yahoo 中搜 搜狗等等都使出浑身解数吸引着网民的眼球 这些大网站可谓是各有所长 总的来说虽然他们搜索功能都很强 但是搜索得到的结果基本上是千篇一律 信息的冗余量很大 网民不得
  • jenkins持续集成源码管理选项为None,构建失败找不到git.exe解决办法

    我的jenkins版本为Jenkins ver 2 19 1 1 源码管理选项只有None的解决办法 在插件管理中心 搜索对应的源码管理插件这里以git为例 搜索git plugin点击右下角的安装方式 在线安装需要连接VPN你懂的 如下图
  • 查询按键控制数码管的显示

    一 仿真电路图 二 c语言代码 include at89x51 h unsigned int j unsigned char i k cz unsigned char code a 0x3f 0x06 0x5b 0x4f 0x66 0x6d
  • 10 个用于 Linux 的开源轻量级 Web 浏览器

    导语 在一些快速对比之后 本文发现了一些适用于 Linux 的轻量级 Web 浏览器 推荐给大家 希望大家有所裨益 不过需要注意的是 文章所提及的浏览器并没有做过任何基准测试 因此适用于 Linux 系统的东西可能不适用于其他系统 作者 M
  • 实际生产环境Apache RocketMQ消息体过大的解决方案

    前言 官方定义消息体默认大小为 4MB 普通顺序消息类型 事务 定时 延时类消息默认大小为64KB 如果超过限制则会抛出异常 但实际工作中 需要使用到MQ进行异步解耦 传输的业务消息偶尔会遇到超过4MB 尤其在业务复杂的系统中 那么我们应该
  • 牛客网笔试输入输出的一堆坑。。(Python)

    牛客网笔试的时候Python的输入输出是真的很坑 有时候线下自测案例是正常的 线上却怎么都调不过去 这里简单记录一下 一 常见输入输出的写法 1 input 直接使用input 读取回来的是字符串 比如输入为 abds n就为 abds n
  • Ubuntu 18.04 的安装及基础操作流程

    目录 一 Ubuntu 的安装及设置网络参数 1 Ubuntu 的安装 2 设置网络参数 二 将apt get源更换为清华源 1 备份原文件 输入sudo cp etc apt sources list etc apt sources li
  • 天天给 App 抓包,还不懂 HTTP 代理吗?

    一 序 今天来和大家一起聊聊 HTTP 代理 在 HTTP 协议中 最基础的就是请求和响应的报文 而报文又由报文头和报文实体组成 大多数 HTTP 协议的使用场景 都是依赖设置不同的 HTTP 请求 响应 的 Header 来实现的 既然要
Powered by Hwhale