浅谈HTTPS通信机制和Charles抓包原理

转载请注明出处:https://blog.csdn.net/zwjemperor/article/details/80719427
主页:https://blog.csdn.net/zwjemperor

前言


网络请求是应用开发的基础,在开发过程中经常需要通过抓包来分析网络问题,了解HTTP基础知识和HTTPS通信机制对提高开发效率来说必不可少。在这篇文章里,我将介绍三部分的内容:

  1. HTTP基础知识:URL和报文结构
  2. 浅谈HTTPS通信机制,HTTPS是如何进行安全通信的?
  3. 浅谈HTTPS抓包原理,为什么Charles能够抓取HTTPS报文?

1. HTTP基础知识:URL和报文结构


1.1 URL

统一资源定位符(Uniform Resource Locator)是网络资源的位置和访问方法的简洁表示。

常见的url包括4个部分,结构如下图:

URL结构

组件含义
方案使用的协议,如http或https
主机服务器的域名或IP地址
路径服务器上资源的本地名,用(/)与前面的scheme分隔开来
查询字符串通过查询字符串来减小请求资源类型的范围,如参数

url的详细介绍可参考:统一资源定位符

1.2 报文

HTTP报文就是网络传输的信息,包括3个部分:起始行、首部(Header)、主体
报文分2类:发送请求的报文称为请求报文,响应请求的报文称为响应报文

1.2.1 请求报文

请求报文

1.2.1.1 请求行

请求报文的起始行称为请求行,包含 请求方法、地址、HTTP版本 3个部分,格式为:

[空格][空格]

请求行以CRLF字符结束,请求方法、地址、HTTP版本之间以空格隔开。
如上面的请求报文中,请求方法为GET,地址为/static/search/baiduapp_icon.png,HTTP版本为1.1。

http最常用请求方法为GET和POST。

方法作用
GET从服务器获取资源
POST向服务器发送需要处理的数据,如提交表单

1.2.1.2 请求首部(Header)

起始行后面有零个或多个首部字段,每个首部字段都是一个键值对,首部以一个空行结束。
Header可以向服务器提供一些额外的信息,比如客户端希望接收什么类型的数据。常见的请求Header如下:

首部描述
Host请求的服务器主机名
User-Agent应用程序标识,如系统版本和浏览器版本
Accept客户端能够接受的数据类型
Accept-Encoding客户端能够接受的编码方式
Accept-Language客户端能够接受的语言
Cookie向服务器传递的cookie

1.2.1.3 请求主体

请求主体是可选的,接在首部的空行之后,包含了要发送给服务器的数据,主体中可以包含任意的文本或二进制数据,比如图片、视频、音轨、软件程序。

1.2.2 响应报文

响应报文

1.2.2.1 响应行

响应报文的起始行称为响应行,包含 HTTP版本、状态码、原因短语(解析状态码的文本,可选) 3部分,格式为:

[空格][空格]

响应行同样以CRLF字符结束,HTTP版本、状态码、原因短语之间以空格隔开。
如上面的响应报文中,HTTP版本为1.1,状态码为200,原因短语为OK。

方法是客户端告诉服务器要什么事情,状态码则是服务端用来告诉客户端事情的处理结果。
状态码是3位的整数值,上面的例子状态码为200,表示处理成功,状态码分类如下:

整体范围分类
100~199信息提示
200~299成功,如200
300~399重定向
400~499客户端错误,如404
500~599服务器错误,如500

详细状态码分类可参考:HTTP状态码详解

1.2.2.2 响应首部(Header)

和请求首部一样,响应首部也是由键值对构成,以空行结束,提供更多有关响应的信息,常见的响应首部如下:

首部描述
Content-Length主体的长度或尺寸
Content-Type主体的对象类型
Date服务器时间
Server服务器类型
Set-Cookie设置Cookie

1.2.2.3 响应主体

与请求主体一样,响应主体也是可选的,接在首部的空行之后,包含了要发送给客户端的数据,可以包含任意的文本或二进制数据。


2. 详谈HTTPS通信机制,HTTPS是如何进行安全通信的?


首先来看一种场景:小红发信息约小明放学后去电影。

正常的信息流动是这样的:

1.小红 -> 放学后去看电影吧? -> 小明
2.小明 -> 好,校门口等我。 -> 小红

但如果存在一个中间人把小红和小明的信息拦截,并做了修改,信息流变成了下面这样:

1.小红 -> 放学后去看电影吧?-> 中间人(你) -> 今天上课有点累,放学我就回家了,不要等我。 -> 小明
2.小明 -> 好吧,好好休息。 -> 中间人(你) -> 不去了,放学后我就回家。 -> 小明

小红以为小明不陪自己看电影,小明以为小红放学就回家了,而你就找了个理由约上小红去看电影了。

之所以会产生误解,是因为小红和小明没办法验证对方信息的真假,都以为收到了对方的正确信息,这是个典型的中间人攻击的例子。

HTTPS正是要解决这个问题,在HTTP传输层之上加了一个安全层(SSL或TLS协议实现),可以做到以下3点:

  • 数据的保密性
  • 校验双方身份的真实性
  • 数据的完整性

下面来看https是如果解决这3个问题的。

2.1 数据的保密性

数据要保密,就需要对数据进行加密。加密算法可以分为2类,一类是对称加密算法,另一类是非对称加密算法。

对称加密算法,加密和解密使用相同的密钥,优点是加密速度快,缺点是如果密钥泄露的话就无法做到保密了。常见的对称加密算法有DES、AES等。

非对称加密算法,又叫公开密钥加密。需要有2个密钥,公钥和私钥,公钥向所有人公开,私钥不公开。用公钥加密的数据只有私钥才能解密;反之,用私钥加密的数据只有公钥才能解密。因为这种特性,非对称加密算法可以用来校验数字签名,下面会具体讲解。

很显然,仅使用对称加密算法是不现实的,互联网中通信的双方大多是临时建立的连接,不可能提前协商好密钥,而且密钥也要进行传输,无法保证密钥本身的安全性。

如果使用非对称加密,客户端向服务器发送数据是安全的,客户端用服务器的公钥进行加密,只有服务器用自己的私钥才能解密。但如果服务器用私钥对数据进行加密,则所有人都可以用公钥进行解密,这是不安全的。

HTTPS的解决方案是这样的:用非对称算法随机加密出一个对称密钥,然后双方用对称密钥进行通信。具体来说,就是客户端生成一个随机密钥,用服务器的公钥对这个密钥进行非对称加密,服务器用私钥进行解密,然后双方就用这个对称密钥来进行数据加密了。

2.2 校验双方身份的真实性

上面说了加密,保证了数据不能被他人读取,但通信的双方怎样校验对方的身份呢?HTTPS使用了数字证书,数字证书就是身份认证机构(Certificate Authority)盖在数字身份证上的一个章或印(或者说加在数字身份证上的一个签名),这一行为表示身份认证机构已认定这个人。证书的合法性可以向CA验证。

数字证书主要包含以下信息:
* 证书颁发机构
* 证书颁发机构签名
* 证书绑定的服务器域名
* 证书版本、有效期
* 签名使用的加密算法(非对称算法,如RSA)
* 公钥

客户端收到服务器的响应后,先向CA验证证书的合法性(根据证书的签名、绑定的域名等信息),如果校验不通过,浏览器会中止连接,向用户提示证书不安全。

需要提一点的是,证书的制作方法是公开的,任何人都可以自己制作证书,所以有些公司不向CA申请,比如12306。但自己制作的证书是得不到CA认证的,所以访问12306网站时,浏览器会有证书不合法的提示,如下图,只有用户选择信任该网站时,才能继续访问。

证书校验不合法提示

2.3 数据的完整性

网络传输过程中需要经过很多中间节点,虽然数据无法被解密,但可能被篡改,那如何校验数据的完整性呢?通过校验数字签名,流程见下图:

数字签名校验

首先来了解下哈希算法,哈希算法能够将任意长度的字符串转化为固定长度的字符串,该过程不可逆,可用来作数据完整性校验。

服务器在发送报文之前做了3件的事:
* 用哈希算法对报文提取定长摘要
* 用私钥对摘要进行加密,作为数字签名
* 将数字签名附加到报文末尾发送给客户端

客户端接收到报文后:
* 用公钥对服务器的数字签名进行解密
* 用同样的算法重新计算出报文的数字签名
* 比较解密后的签名与自己计算的签名是否一致,如果不一致,说明数据被篡改过。

同样,客户端发送数据时,通过公钥加密报文摘要,服务器用私钥解密,用同样的方法校验数据的完整性。

2.4 HTTPS通信的大致过程

HTTPS通信过程

  1. 客户端将自己支持的加密算法发送给服务器,请求服务器证书;

  2. 服务器选取一组加密算法,并将证书返回给客户端;

  3. 客户端校验证书合法性,生成随机对称密钥,用公钥加密后发送给服务器;

  4. 服务器用私钥解密出对称密钥,返回一个响应,HTTPS连接建立完成;

  5. 随后双方通过这个对称密钥进行安全的数据通信。


3. 浅谈HTTPS抓包原理,为什么Charles能够抓取HTTPS报文?


在一节中,我们分析了HTTPS的安全通信过程,知道了HTTPS可以有效防止中间人攻击。但用过抓包工具的人都知道,比如Charles,Fiddler是可以抓取HTTPS请求并解密的,它们是如何做到的呢?

首先来看Charles官网对HTTPS代理的描述:

Charles can be used as a man-in-the-middle HTTPS proxy, enabling you to view in plain text the communication between web browser and SSL web server.

Charles does this by becoming a man-in-the-middle. Instead of your browser seeing the server’s certificate, Charles dynamically generates a certificate for the server and signs it with its own root certificate (the Charles CA Certificate). Charles receives the server’s certificate, while your browser receives Charles’s certificate. Therefore you will see a security warning, indicating that the root authority is not trusted. If you add the Charles CA Certificate to your trusted certificates you will no longer see any warnings – see below for how to do this.

Charles作为一个中间人代理,当浏览器和服务器通信时,Charles接收服务器的证书,但动态生成一张证书发送给浏览器,也就是说Charles作为中间代理在浏览器和服务器之间通信,所以通信的数据可以被Charles拦截并解密。由于Charles更改了证书,浏览器校验不通过会给出安全警告,必须安装Charles的证书后才能进行正常访问。

下面来看具体的流程:

Charles抓取HTTPS流程

  1. 客户端向服务器发起HTTPS请求

  2. Charles拦截客户端的请求,伪装成客户端向服务器进行请求

  3. 服务器向“客户端”(实际上是Charles)返回服务器的CA证书

  4. Charles拦截服务器的响应,获取服务器证书公钥,然后自己制作一张证书,将服务器证书替换后发送给客户端。(这一步,Charles拿到了服务器证书的公钥)

  5. 客户端接收到“服务器”(实际上是Charles)的证书后,生成一个对称密钥,用Charles的公钥加密,发送给“服务器”(Charles)

  6. Charles拦截客户端的响应,用自己的私钥解密对称密钥,然后用服务器证书公钥加密,发送给服务器。(这一步,Charles拿到了对称密钥)

  7. 服务器用自己的私钥解密对称密钥,向“客户端”(Charles)发送响应

  8. Charles拦截服务器的响应,替换成自己的证书后发送给客户端

  9. 至此,连接建立,Charles拿到了 服务器证书的公钥 和 客户端与服务器协商的对称密钥,之后就可以解密或者修改加密的报文了。

HTTPS抓包的原理还是挺简单的,简单来说,就是Charles作为“中间人代理”,拿到了 服务器证书公钥HTTPS连接的对称密钥,前提是客户端选择信任并安装Charles的CA证书,否则客户端就会“报警”并中止连接。这样看来,HTTPS还是很安全的。

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页