一、HTTP的概念

HTTP是超文本传输协议,是一种应用层协议,是基于为浏览器/服务器间提供统一的信息交换格式而出现的,其发展历程为HTTP/1.0、HTTP/1.1、HTTP/2、HTTP/3。

在HTTP/3之前,HTTP都是基于TCP传输的。

二、HTTP报文格式

作为一种应用层协议,其规定的信息交换格式如下:

1. 请求报文

请求报文为主动发送一个http请求的报文,格式说明:

  • 请求行(request line):包括请求方法,资源的URL,以及HTTP协议版本。
  • 请求头(header):包括请求服务器所需要的附加信息。
  • 空行(CRLF):请求头部后面必须是空行,即使请求数据为空,也要有空行。
  • 请求数据(body):也称为请求体,可以添加任意类型的数据,通过请求头中的Content-Length字段确定请求数据的长度。

(1)GET请求报文

根据RFC规范,GET 的语义是从服务器获取指定的资源。GET请求一般不携带请求体,如果有请求参数则放在URL后面,一个GET请求报文的样例如下:

GET /video1" />
响应报文样例:

HTTP常见响应状态码

参考:http协议详解 HTTP 请求报文

三、HTTP 与 HTTPS的区别

  • HTTP是明文传输,HTTPS比HTTP多一层SSL/TLS 安全协议,在TCP的三次握手之后,还需进行TLS握手,握手成功后通过秘钥对整个HTTP报文通过对称加密进行密文传输通信。
  • HTTP 默认端口号是 80,HTTPS 默认端口号是 443。

SSL/TLS 协议基本流程

  • 客户端向服务器索要并验证服务器的公钥。
  • 双方协商生产「会话秘钥」。
  • 双方采用「会话秘钥」进行加密通信。

前两步就是 TLS 握手阶段,握手过程中的密钥交换算法有两种:RSA 算法 和 ECDHE 算法。

1. 基于RSA的TLS握手机制

(1)第一次握手:客户端首先会发一个「Client Hello」消息,其中包括客户端使用的 TLS 版本号、支持的密码套件列表、以及生成的第一个随机数(Client Random)。

(2)第二次握手:当服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否支持,和从密码套件列表中选择一个密码套件,以及生成第二个随机数(Server Random)。接着返回「Server Hello」消息,其中包括确认 的TLS 版本号、选择的密码套件、Server Random。然后,服务端为了证明自己的身份,会发送「Server Certificate」给客户端,这个消息里含有数字证书。随后,服务端发了「Server Hello Done」消息,目的是告诉客户端,我已经把该给你的东西都给你了,第二次握手完毕。

密码套件基本的形式是「密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法」

(3)第三次握手:客户端首先对证书进行验证,认为可信则继续往下走。接着客户端就会生成第三个随机数 (pre-master),用服务器公钥加密后传给服务端。然后客户端用这三个随机数生成一个会话秘钥,用于后续通信的对称加密。生成完「会话密钥」后,然后客户端发一个「Change Cipher Spec」,告诉服务端开始使用加密方式发送消息。然后,客户端再发一个「Encrypted Handshake Message(Finished)」消息,把之前所有发送的数据做个摘要,再用会话密钥(master secret)加密一下,让服务器做个验证,验证加密通信「是否可用」和「之前握手信息是否有被中途篡改过」。

数字证书的签发与验证:

(4)第四次握手:服务端收到加密后的第三个随机数 (pre-master)后,用服务端私钥进行解密,然后进行与客户端同样的操作:用这三个随机数生成同样的会话秘钥、发送「Change Cipher Spec」、发送会话秘钥加密后的摘要信息「Encrypted Handshake Message(Finished)」。之后客户端和服务端就可以开始用会话秘钥加密通信了。

2. 基于ECDHE的TLS握手机制

使用 RSA 密钥协商算法的最大问题是不支持前向保密。

因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务端收到后,会用私钥解密得到随机数。所以一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。

为了解决这个问题,后面就出现了 ECDHE 密钥协商算法,我们现在大多数网站使用的正是 ECDHE 密钥协商算法。

参考:

  1. https://xiaolincoding.com/network/
  2. https到底把什么加密了?