本文想要用最精简的文字对HTTP/1.x、HTTP/2、HTTPS做一个总结,希望能够帮助大家快速回顾、节省时间。
目录
- 什么是HTTP
- 什么是HTTPS
- 什么是HTTP/2
1 什么是HTTP
HTTP全称是HyperText Transer Protocol,超文本传输协议,用于Web服务端和客户端之间的数据传输。
HTTP是应用层协议,位于OSI 7层网络模型的最上层,基于TCP协议。
1.1 HTTP消息
HTTP报文格式非常简单,只有两种,客户端发送给服务器的称为请求(Request),服务端返回的称为响应(Response)。请求和响应都由3部分组成:
Request
GET / HTTP/1.1
Host: localhost:8000
User-agent: Mozilla/5.0
id=123
起始行
指明了HTTP方法、URL和HTTP版本。
方法有:GET HEAD POST PUT DELETE CONNECT等
目前(2019)主要的版本是HTTP/1.1和HTTP/2,34%的网站使用HTTP/2。
首部字段
首部可省略。每行表示一个字段,格式为Key: Value。
主体
主体可省略。主体和首部之间必须有一个换行(CRLF)。主体用于传输数据。
Response
HTTP/1.1 200 OK
Server: Apache
Content-Encoding: gzip
Connection: keep-alive
Hello
状态行
协议版本,状态码(表示请求处理的结果),状态文本
状态码从1xx到5xx,分为5类,
首部字段
与Request的首部相同
主体
主体可省略,同样要有换行。对于网页请求,这里返回的就是HTML。
1.2 HTTP连接
OK,消息格式讲完了,接着我们来看看HTTP连接是怎么建立的。
- 首先当然是TCP 3次握手啦
- 客户端发送Request
- 服务器处理请求,返回Response
keep-alive
HTTP/1.0之前,第3步完了就会关闭连接,每次请求都要重新建立连接,非常消耗资源。HTTP/1.0,首部可以包含Connection: keep-alive字段,表示不关闭连接,默认是10秒左右,这期间有新的请求就可以继续使用这个TCP连接发送。到了HTTP/1.1,省略这个字段,默认连接就是keep-alive,除非显式包含Connection: close字段。
但是即使复用了这个连接,请求还是只能一个一个发送,当前一个Response回来的时候,才能发送下一个Request,如图。
pipeline
pipeline可以让客户端一次发出多个请求,然后服务端按顺序返回响应,进一步降低延迟。如图。
2 什么是HTTPS
HTTP是明文传输的,信息很容易被窃取或篡改,非常不安全。因此提出了加密传输方案,在HTTP和TCP之间提供一个用于加密的中间层——Secure Socket Layer(SSL),升级版改名为Transport Layer Security(TLS),两者在原理上没有太大区别,所以经常放在一起讨论。
我们把使用了SSL/TLS的HTTP协议称为HTTPS协议。
2.1 SSL/TLS加密原理
假设这样一个场景,让我们回到中学传纸条的年代。A和B想传纸条,中间要经过C同学帮忙传递。这就是明文的HTTP,他俩交流的任何内容C都可以看到。
传纸条加密
假设AB已经掌握了一种简易的对称加密技术:将文字用拼音代替,只使用26个字母通信,对字母表做一个+X映射,比如X等于2,那么A就变成C,B变成D,以此类推。X就相当于密钥。
问题在于,如果A和B在纸条中协商密钥,那么C也可以看到,所以等于没加密。
这时他们想到了一种简易的非对称加密技术——可以上锁的文具盒和一把钥匙,不需要钥匙就可以上锁,但只能用钥匙打开。只要把纸条锁起来再传递C就看不到了。但是一直用文具盒传纸条成本太高:上锁开锁浪费时间,体积大传递费力,也容易被老师发现。
所以综合起来,我们可以使用文具盒协商密钥,协商完了就切换为对称加密。既保证了安全性,又没有增加过多成本。
最终场景就是:
- 假设B持有文具盒和钥匙,A先传一个文明纸条,表示想要进行加密通信。
- B把没上锁的文具盒传回来,A写一个任意数字作为对称加密的密钥,锁起来传给B
- B用钥匙打开,得到密钥,以后纸条信息都通过这个密钥加密,不需要再使用文具盒。由于C不知道密钥,所以看到纸条也没法解密。
对称加密和非对称加密
幸运的是,数学上确实存在非对称加密的方法,非常类似锁和钥匙的机制。非对称加密有2个密钥,1个公钥(Public Key)和1个私钥(Private Key)。公钥可以给任何人看到,公钥加密的数据,只有私钥才能解密。反过来,只有私钥可以对数据签名,任何有公钥的人都能验证这个签名是否正确(从而证明私钥持有人的身份)。
天下没有免费的午餐,非对称加密这么好,不能不付出代价。缺点就是计算成本高,实现复杂,数据包大。
比如AES-256是256位密钥的对称加密算法,要达到同样的安全性,非对称加密需要更长的密钥,ECC需要512位,RSA需要15424位。
所以SSL/TLS跟传纸条一样,也只用非对称加密进行协商,协商结束就切换为对称加密。
2.2 SSL/TLS连接过程
首先是建立TCP连接,然后建立SSL/TLS连接,SSL/TLS连接过程如图所示。
大致要经过以下5个步骤:
- 客户端发送hello包,包含版本、支持的加密算法列表、会话信息等
- 服务端选择一个双方都支持的加密算法,回复hello包,包含版本、加密算法、会话信息、证书信息等(相当于公钥)
- 客户端验证证书有效性(名称、日期、颁发机构),然后随机创建一个密钥,Pre-Master Secret,用服务端公钥加密这个密钥,发给服务端
- 客户端发送Finished消息,使用约定的加密算法和Pre-Master Secret加密,表示客户端握手完成
- 服务端使用同样的算法和密钥,发送Finished消息,表示服务端握手完成
到此SSL/TLS连接就正式建立了,之后就能用约定的对称加密算法来通信了。
2.3 HTTPS的安全性
总结一下,基于SSL/TLS的HTTPS协议,提供了哪些安全性呢?
信息安全有个经典评价指标CIA:Confidentiality(机密性)、Integrity(完整性)、Availability(可用性)
指标 | 是否满足 | 描述 |
---|---|---|
Confidentiality 机密性 | 是 | 通信过程加密,别人窃取到也是乱码 |
Integrity 完整性 | 是 | 结果是完整的,不能被篡改。SSL/TLS除了加密,还可以计算摘要(哈希),从而防止篡改 |
Availability 可用性 | 否 | 与HTTP的Availability基本相同,比如遭受拒绝服务攻击等 |
除此之外,HTTPS还提供了Authentication(认证),通过验证服务端的证书,保证了你访问的网站是正确的,不会受攻击跳转到恶意网站。还要补充一点,服务端同样可以要求验证客户端的证书,以实现双向的Authentication。
最后,Anonymity(匿名性),由于HTTPS底层还是TCP/IP协议,IP和端口号是没法加密的,否则路由都不知道你的包要发给谁。你是谁(IP+端口),你访问了哪个网站(主机名+IP+端口),这些都是没有加密的。所以,不要以为HTTPS就可以为所欲为了。
3 什么是HTTP/2
如果要用一句话描述HTTP/2做了什么,那就是大幅降低网络延迟,与HTTP/1.x相比加载时间缩短30-60%。在这里可以测试HTTP/2的速度。
HTTP/2并没有推翻重来,只是对HTTP/1.x的升级和优化,保留了现有全部特性和结构。
3.1 HTTP/1.x的问题
HTTP/1.x高延迟的罪魁祸首是TCP利用率低。表现为以下几个方面:
Pipeline队头阻塞问题(Head-of-line blocking):还记得HTTP连接那节提到的Pipeline吗,客户端一次发送多个请求,服务端按顺序处理。如果队头的请求要花很长时间才能处理完,那后面的请求只能被迫阻塞。
首部字段不压缩,而且多次请求的情况下,同样的首部字段被重复发送,增加了数据量。
由于需要请求的资源数较多,浏览器会同时发起多个并发连接,但更多的连接意味着更多TCP握手,反而增加了网络开销,在网络不好的情况下,更是会加重网络拥堵。
3.2 HTTP/2特性
二进制分帧(Binary Framing)
HTTP/2的消息是二进制格式的,跟HTTP/1.x的文本形式相比,二进制更容易解析,更高效。分割粒度也更小,以前以HTTP消息为单位传输,现在将消息分割成帧(Frame)。规范中定义了10种不同的帧,比如HEADERS、DATA帧对应HTTP/1.x的首部和主体,WINDOW_UPDATE, PUSH_PROMISE等用于支持HTTP/2的新特性。
帧格式如图所示。包含长度、类型、标志、Stream ID、数据这几个字段。长度是24位无符号整形,默认14位,超过2^14=16384需要通过SETTINGS帧设置。
消息和帧的关系如下图所示。
多路复用(Multiplexing)
多路复用实现了连接共享,对于同一来源,只需要建立一个TCP连接,所有HTTP消息共享这个连接。
一个HTTP/2连接包含多个数据流(Stream),�数据流是双向字节流,可以承载一条或多条消息。一个数据流包含多个Frame。Frame是最小的传输单位,接收端根据Stream ID将收到的Frame组装成HTTP消息。
如下图所示,客户端正在向服务器传输一个DATA帧(数据流5),同时,服务器正向客户端交错发送数据流1和数据流3的帧。因此,一个连接上同时有3个并行的数据流。
这种方式大幅提高了TCP利用率,从而带来巨大的性能提升。我们可以并行发送多个请求和响应,互不影响。
优先级和依赖
在交错传输数据流的时候,我们通过设置优先级或依赖关系的方式,来调整响应顺序。
- 优先级:一个1到256的整数,表示这个流的权重,服务器会根据优先级来选择应该先处理哪些流。
- 依赖:客户端可以告知服务器当前流依赖于其他哪个流,建立一个依赖树,”子流“会依赖于”父流“的传输完成情况。
比如当用户快速滚动一个全是图片的页面的时候,已经滑过去的图片和当前屏幕中的图片正在同时加载,为了提升体验,我们应该将当前屏幕中的图片设置更高的优先级。
首部压缩
之前提到HTTP/1.x的首部字段不压缩,通常会给每个传输增加500-800字节的开销。HTTP/2使用HPACK压缩格式压缩首部数据,同时双方还需要维护一个索引表,之前见过的字段就不用重复发送了。
与HTTP/1.x相比,压缩将首部大小减小了85%左右。
流控制
HTTP/2的流控制类似于TCP滑动窗口,双方通过设置各自的窗口大小,表示还能接收多少数据。既可以对某个数据流控制,也可以对整个连接进行控制。每当发送方发出DATA帧时窗口减小,在接收方发出WINDOW_UPDATE帧时增大。
流控制可以在很多场景用到,比如用户暂停了视频,希望暂停或者限制视频加载。再比如可以只加载图片的一部分作为预览图,然后再逐个加载。
服务器推送
服务器可以对一个客户端请求发送多个响应。当客户端请求资源X,服务器知道它很可能也需要资源Y的情况下,就会主动将资源Y推送给客户端,客户端缓存起来以备使用。
服务器通过PUSH_PROMISE帧发起推送,客户端可以接收,或者通过RST_STREAM帧拒绝(例如该资源已经缓存了)。
参考链接
MDN| HTTP
HTTP/2
Google| HTTP/2简介
GitBook http2讲解
Cryptographic security protocols: SSL and TLS
How Does HTTPS Work? RSA Encryption Explained