第8期《透视HTTP协议》笔记

371 阅读30分钟

01 | 时势与英雄:HTTP的前世今生

美国国防高等研究计划署(ARPR)建立了ARPR网,它有四个分布在各地的节点。

基于对ARPR网的实践和思考,研究人员发明出了著名的TCP/IP协议。

确立了三项关键技术:URI HTML HTTP。

HTTP/0.9,仅允许GET动作,并且响应请求后就立即关闭连接。

HTTP/1.0,增加HEAD/POST等新方法,增加响应状态码等等。形式上与我们现在的HTTP差别不大。但HTTP/1,0还不是标准。

HTTP/1.1,网景和微软开启著名的浏览器大战,最后微软取得胜利。这推动Wbe发展,HTTP/1.0经受实践检验,于是HTTP/1.1发布了RFC文档。增加了PUT/DELETE等方法,增加了Host头等。

HTTP/2,因为对HTTP/1.1的连接慢无法跟上迅猛发展的互联网,Google决定做出改变。首先开发了Chrome并推出新的SPDY协议并且应用在自家的服务器,用实际行动倒逼HTTP协议变革。开启了第二次浏览器大战。于是互联网标准化组织以SPDY为基础定制新版本的HTTP协议,即HTTP/2。但HTTP/2普及率较低,多数网站使用的仍然是HTTP/1.1。

HTTP/3,在HTTP/2还处于草案的时候,Google又发明了一个新的协议QUIC,2018年互联网标准化组织IETF提议将QUIC更名为HTTP/3。HTTP/3是将来发展的方向。

02 | HTTP是什么?HTTP又不是什么?

HTTP(超文本传输协议)

协议:HTTP是一个用在计算机世界里面的协议,它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范,以及相关的各种控制和错误处理方式。

传输:HTTP是一个在计算机世界里专门用来在两点之间传输数据的约定和规范,是一个双向协议。

超文本:超越普通文本的文本,是文字、图片、视频、音频等的混合体,关键是含有超链接,从而形成复杂的非线性、网状的结构关系。

总结:HTTP是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。

HTTP不是互联网、编程语言、html、不是孤立的协议。

HTTP通常跑在TCP/IP协议栈之上,通过IP协议寻址,TCP实现可靠数据传输,DNS实现域名查找,SSL/TLS实现安全通信等等协议之间相互交织构成一个协议网,HTTP则处于中心地位。

03 | HTTP世界全览(上):与HTTP相关的各种概念

网络世界

互联网世界是由数不清的大小岛屿组成的"千岛之国"。每个岛屿可能是个局域网也可能是个广域网,也可能是基站、热点构成的移动网络,也可能是电缆、光纤构成的固定网络。

万维网只是互联网的一个子集,万维网基于HTTP协议,但能力也就被限制在HTTP协议内。

除了万维网还有很多其他的资源,例如电子邮件、FTP、BT等,它们需要各自的专有协议来访问,但是由于HTTP灵活,所以它们也经常被包装成HTTP来访问,就是我们进场看到的邮箱网页版、微信网页版。

Web Server

一般有两层含义。 硬件:物理形式或云形式的机器。 软件:提供Webo服务的应用陈旭,通常运行在硬件含义的服务器上。

CDN

内容分发网络 应用HTTP协议里的缓存和代理技术,代替源站响应客户端的请求。

爬虫

HTTP协议并没有规定用户代理后面必须是人类,也可以是机器人,这类机器人就叫爬虫。但是也会过度消耗网络资源,占用服务器和带宽,影响对真实数据的分析,所以出现了反爬虫技术。

WebService

与Web Server不同,是一种应用服务开发规范,是一种基于Web(HTTP)的服务架构技术。

WAF

网络应用防火墙,专门检测HTTP流量,是防护Web应用的安全技术,通常位于Web服务器之前,可以组织SQL注入、跨站脚本等攻击。

04 | HTTP世界全览(下):与HTTP

TCP/IP

TCP/IP协议其实是一系列网络通信协议的统称,最核心的是TCP和IP,其他还有UDP、ICMP、ARP等等共同构成一个复杂但有层次的协议栈。协议栈有四层,分别是应用层、传输层(TCP)、网际层(IP)。IP协议主要解决寻址和路由的问题。TCP基于IP提供可靠的、字节流形式的通信。

DNS

域名系统:用有意义的名字来作为IP地址的等价替代。但是想要使用TCP/IP协议来同喜仍然要使用IP地址,所以通过域名解析,把需要的域名做一个转换,映射到真实的IP。

URI/URL

URI:唯一的标记互联网上的资源。 URL:URI实现的一种形式,是URI的一个子集。

HTTPS

运行在SSL/TLS上的HTTP,SSL/TLS建立在TCP/IP之上,负责加密通信的安全协议。SSL/TLS使用了许多密码学最先进的研究成果,综合对称加密、非对称加密、摘要算法、数字签名、数字证书等技术。

代理

匿名代理:完全隐匿了被代理的机器,外界只能看到代理服务器。

透明代理:外界不仅知道代理的存在,也知道客户端的存在。

正向代理:靠近客户端,代表客户端向服务器发送请求。

反向代理:靠近服务器端,代理服务器响应客户端的请求。

05 | 常说的“四层”和“七层”到底是什么?“五层”“六层”哪去了?

TCP/IP网络分层

链路层

网际层(IP协议)

传输层(TCP协议)

应用层

OSI网络分层模型

物理层

数据链路层

网路层

传输层

会话层

表示层

应用层

两个分层模型的映射关系

OSI发布的时候,TCP/IP已经在许多网络上实际运行,所以发布的时候也明确表示是一个参考。

06 | 域名里有哪些门道?

IP协议将MAC编号转换成了四位数字,对物理网卡的MAC地址做了一层抽象。

但依旧不容易记忆,所以有了域名系统,将数字IP再做一层抽象。

当我们需要访问主机的时候,就需要经过域名解析。全世界网民那么多,我们不得不想办法采取一些手段减轻域名的压力。

许多大公司、网络运营商都会建立自己的DNS服务器,代理用户访问DNS系统,他们会存储之前查询过的结果,如果已经有记录,就直接返回IP地址,无需再次向根服务器发起查询。

其次,操作系统也会帮我们去进行缓存。再者,我们的操作系统的host文件,我们可以去设置,如果操作系统的缓存找不到记录,就会去host文件查找。

07 | 自己动手,搭建HTTP实验环境

基础篇 (7讲)

08 | 键入网址再按下回车,后面究竟发生了什么?

域名解析,浏览器先看自己的缓存有没有,没有则在操作系统的缓存找,还没有就在hosts文件找,还没有就向DNS找。 建立连接,发送数据。 ACK可以当做收到回复来理解

09 | HTTP报文是什么样子的?

TCP的报文格式 HTTP的报文格式类TCP报文格式,注意有一行空白行。 相对应如下,下面的示例没有实体。 HTTP报文分成请求报文和响应报文,主要区别在起始行。 请求报文中起始行叫做请求行

请求方法/请求目标/版本号。例如:GET / HTTP/1.1 响应报文中起始行叫状态行

版本号 状态码 原因。例如:HTTP/1.1 200 OK

头部字段

基本上可以分类为通用字段、请求字段、响应字段、实体字段。头部字段不区分大小写,顺序随意,除了规定的标准头,也可以任意添加自定义字段,实现功能扩展。

Host(请求头)

HTTP/1.1请求头中必须出现的字段,告诉服务器这个请求应该由哪个主机来处理。

User-Agent(请求头)

使用一个字符串来描述发起HTTP请求的客户端,服务器可以根据它来返回最适合此浏览器显示的页面,有的爬虫还会在这里用spider表明自己是爬虫,可以利用这点进行反爬虫,但是由于历史原因,User-Agent非常混乱,每个浏览器都自称是Mozilla、Chrome、Safari,就变得没有意义。

Date(通用)

表示报文创建的时间。

Server/X-Powered-By (响应头)

告诉客户端正在提供Web服务的软件名和版本号。但是这会把服务器的一部分信息暴露出去,所有有的网站要么没有这个字段要么返回一个无关的值。

X-Powered-By是非标准字段,表示服务器使用的编程语言。

Content-Length(通用)

表示报文实体的长度,服务器看到这个字段就知道后续有多少数据可以直接接收,否则body就是不定长,则使用chunked方式分段传输。

10 | 应该如何理解请求方法?

标准请求方法

客户端发出一个动作指令,要求服务器端对URI定位的资源执行这个动作。服务器端也可以拒绝执行或者改变动作的含义,毕竟客户端只是发出一个指示,例如客户端发起一个请求某个文件的请求,但是这个这个文件的保密性比较高,所以服务器可以有如下几种响应方式:

1、假装文件不存在,返回404。

2、告诉你有这个文件,但是不允许访问,返回403。

3、用Allow头告诉你可以用HEAD方法获取文件的元信息,返回405。

http/1.1规定的八种方法。

1、GET

获取资源,可以理解为读取或者下载数据。匹配URI和其他头字段就能实现对资源更精细的操作。

例如:

在URI后使用"#"就可以在获取页面后直接定位到某个标签所在的位置。

使用If-Modified-Since字段。第一次请求服务器资源,服务器返回Last-Modified字段,当再次请求该资源的时候就会把If-Modified-Since带过去,值为Last-Modified。这样仅当资源被修改时才会执行获取动作。节省网络流量。

Range字段。 Range:0-xxx

响应头 206/416 Accept-Ranges: bytes/Accept-Ranges: none Content-Range:0-xxx

服务器会首先通过Accept-Ranges: bytes或者Accept-Ranges: none告知客户端是否支持。

支持的话客户端发送请求带Range:0-xxx可以只请求部分文件,返回206,并设置Content-Range,如果0-xxx,xxx超过该资源的范围,则返回416。

2、HEAD

获取资源的元信息。可以看做GET请求的简化版,响应头与GET请求一样。应用场景例如只是想检查一个文件是否存在,只是想看看这个文件是否是最新版,通过服务器返回的文件修改时间可以获取。

3、POST

向资源提交数据,相当于写入或上传数据。

4、PUT

类似POST。与POST不同在于,POST表示新建,而PUT表示updata。但是在实际中PUT用的很少。

5、DELETE

删除资源。但是这个动作比较危险,所以服务器一般不真正的执行删除操作或者直接不处理。

6、CONNECT

建立特殊的连接隧道。一个比较特殊的方法,要求服务器为客户端和另一台远程服务器建立一条特殊的连接隧道,此时服务器充当一个代理的角色。

7、OPTIONS

列出可对资源实行的方法,在响应头的Allow字段返回。功能有限而且用处不大,有的服务器干脆没有实现对它的支持。

8、TRACE

追踪请求-响应的传输路径。对HTTP链路的测试或诊断,可以显示出请求-响应的传输路径,但是会泄露网站的信息,所以通常也是禁用的。

除了以上的八种方法也可以自定义一些请求方法,体现了HTTP协议良好的扩展性。

安全与幂

在HTTP协议里,所谓安全是指请求方法不会破坏服务器上的资源,即不会对服务器上的资源造成实质的修改。

例如:

安全的请求:GET、HEAD

不安全的请求:POST、PUT、DELETE

幂指多以执行相同的操作,结果是一样的。例如GET、HEAD、PUT、DELETE是幂等的,POST不是幂等,因为POST是创建而PUT是更新。

11 | 你能写出正确的网址吗?

URI的格式

scheme 协议名

host 主机名

port 端口号

query 查询参数

fragment 片段标识符

user:passwd@ 身份信息 不推荐使用,因为把敏感的信息暴露出来,存在安全隐患。

http://nginx.org
http://www.chrono.com:8080/11-1
https://tools.ietf.org/html/rfc7230#tag=1
file:///D:/http_study/www/

http://www.chrono.com:8080/11-1?夸父逐日
会被转义成
http://www.chrono.com:8080/11-1?%E5%A4%B8%E7%88%B6%E9%80%90%E6%97%A5

12 | 响应状态码该怎么用?

1xx

提示信息,标识目前是协议处理的中间状态,还需要后续的操作。实际应用少,偶尔遇见的是101,意思是客户端使用Upgrade头字段,要求在HTTP协议的基础上改成其他的协议继续通信。

2xx

成功 报文已经收到并被正确处理。200一般会返回body,204则没有body,206表示body是部分资源。

3xx 重定向

资源位置发生变动,需要客户端重新发送请求。301表示永久重定向,302表示暂时重定向,304表示资源未修改,常用于If-Modieied-Since。

4xx 客户端错误

请求报文有误 服务器无法处理。400是笼统的一个错误表示。403表示服务器禁止访问,404表示服务器无法找到该资源,但目前已被用滥,服务器不开心就会给个404。

5xx 服务器错误

服务器在处理请求时内部发生了错误。500是一笼统的一个错误表示。501表示暂时不支持,502表示后端服务器异常,503表示服务器正忙。

13 | HTTP有哪些特点?

灵活可扩展、可靠传输、应用层协议(不像FTP等只在某个小领域起作用,几乎能够传递一切)、请求-应答通信模式(恰好契合传统C/S系统架构,所以随着互联网发展就出现了B/S架构)、无状态(每个请求互相独立、毫无关联、协议不要求客户端或服务器记录请求相关的信息,减轻服务器的负担,不容易因为装填不一致出错,但也比较麻烦,每次都需要表明身份,增加不必要的数据传输量)

14 | HTTP有哪些优点?又有哪些缺点?

简单、灵活、易于扩展

应用广泛、环境成熟

无状态

明文

类似免费WIFI陷阱,因为HTTP报文明文传输,可以肉眼可见的查看或者修改,所以当你连接WIFI的时候发送的东西如果有密码卡号等等就很危险。

不安全

无法证明你就是你,所以黑客很容易篡改一些内容而我们无法得知是否是真实的。所以出现HTTPS。

性能

不算差也不够好。请求序列中有一个请求因为某种原因被阻塞,在后面排队的所有请求也一并被阻塞,导致客户端迟迟收不到数据。于是诞生了Web性能优化的研究课题,官方的有缓存,非官方的花招就更多了。

进阶篇 (8讲)

15 | 海纳百川:HTTP的实体数据

对于TCP而言,只要把数据传送过去就行,但是对于HTTP这种应用层协议,上层应用就很懵逼。但在HTTP诞生前就有了这种问题的解决方案,即MIME,在HTTP中取了MIME的一部分来标记body的数据类型,就是常听到的MIME type。

MIME type

text、image、audio/video、application(application/json、application/javascript、application/pdf、application/octet-stream)

Encoding type

仅仅有MIME type是不够的,因为HTTP在传输时要压缩数据,所以需要一个Encoding type表明如何解压缩数据。常用的是 gzip、deflate、br这三种。

数据类型使用的头字段

HTTP定义了两个Accept请求头字段和两个Content实体头字段。客户端通过Accept告诉服务器希望得到什么数据,服务器用Content告诉客户端实际发送了什么数据。

Accept-Encoding: gzip, deflate, br
Content-Encoding: gzip

这两个字段可以省略,表明不接受压缩或者没有被压缩。

语言类型使用的头字段

// 语言类型
Accept-Language: zh-CN, zh, en
Content-Language: zh-CN
// 字符集
Accept-Charset: gbk, utf-8
Content-Type: text/html; charset=utf-8

一般请求头只会有Accept-Language,响应头只有Content-Type。

内容协商的质量值

q表示权重来设定优先级 最大值是1。

Accept: text/html,application/xml;q=0.9,*/*;q=0.8

表示最希望使用的是HTML文件,权重是1,其次是XML,权重是0.9,最后是任意数据类型,权重是0.8。

内容协商的结果

响应头的Vary表示服务器在内容协商的时候参考的请求头字段。如下参考的是请求头的Accept-Encoding,User-Agent,Accept。

Vary: Accept-Encoding,User-Agent,Accept

16 | 把大象装进冰箱:HTTP传输大文件的方法

数据压缩

发送请求的时候带着Accept-Encoding,服务器就会从中选择一种压缩算法放进Content-Enoding响应头里。但是对于图片、视频等已经是高度压缩了就失效了,但对文本效果还是很好的。

Transfer-Encoding表示传输时使用了压缩编码传输后会自动解码还原成原始数据,而Content-Encoding则必须由应用自行解码。

分块传输

化整为零的思路在HTTP协议里就是chunked分块传输编码,响应报文里用头字段Transfer-Encoding:chunked表示。可以节约内存和带宽。Transfer-Encoding和Conten-Length是互斥的。

范围请求

有的时候并不需要一个文件的全部而是其中的某个部分,当服务器在相应投资端使用Accept-Range:bytes就可以明确告知客户端支持范围。客户端可以通过头字段Range告诉服务器数据范围。或者服务器也可以不支持范围请求Accept-Range:none;


GET /16-2 HTTP/1.1
Host: www.chrono.com
Range: bytes=0-31

HTTP/1.1 206 Partial Content
Content-Length: 32
Accept-Ranges: bytes
// 96是总长度
Content-Range: bytes 0-31/96

多段数据

Range也支持使用多个"x-y",一次新过去多个片段。 这种情况需要使用一种特殊的MIME类型"multipart/byteranges"表示报文的body是由多段字节序列组成的,并且还要用一个参数"boundary=xxx"给出段之间的分隔标记。


GET /16-2 HTTP/1.1
Host: www.chrono.com
Range: bytes=0-9, 20-29


HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=00000000001
Content-Length: 189
Connection: keep-alive
Accept-Ranges: bytes

--00000000001
Content-Type: text/plain
Content-Range: bytes 0-9/96

// this is
--00000000001
Content-Type: text/plain
Content-Range: bytes 20-29/96

ext json d
--00000000001--

17 | 排队也要讲效率:HTTP的连接管理

早起的HTTP协议使用短连接,收到响应后就立即关闭连接,效率很低。

HTTP/1.1默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率。

服务器会发送Connection:keep-alive表示启用了长连接,提高了传输效率。

报文头里如果有Connection:close就意味着长连接即将关闭。

过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接。

队头阻塞问题会导致性能下降,可以用并发连接和域名分片技术缓解。(并发连接类似多设置几个窗口买东西,域名分片类似多开几家店,也就拥有了更多的窗口)

18 | 四通八达:HTTP的重定向和跳转

重定向是服务器发起的跳转,要求客户端改用新的URI重新发送请求,通常会自动进行,用户是无感知的。

响应头字段Location指示了要跳转的URI,可以用绝对或相对的形式。

使用重定向要小心性能损耗(因为请求了2次)和循环跳转(A->B->C->A)

19 | 让我知道你是谁:HTTP的Cookie机制

Cookies的工作过程

响应头字段Set-Cookie和请求头字段Cookie

Cookie的属性

Cookie中会记录用户识别的信息,所以需要一些手段来防止外泄或窃取,即Cookie的属性。

1、设置Cookie的生存周期

Expires:过期时间 绝对时间点

Max-Age:相对时间 浏览器用收到报文的时间点再加上Max-Age就可以得到绝对时间。

如果不进行指定那么Cookie近在浏览器运行时失效。

2、设置Cookie的作用域

让浏览器仅发送特定的服务器和URI,避免其他网站盗用。

Domain和Path。浏览器在发送Cookie前会从URI提取host和path部分进行对比,如果不满足则不会在请求头里发送。现实中为了省事Path会用/或者直接省略,表示域名下任意路径都允许使用。

3、Cookie的安全性

HttpOnly:告诉浏览器只能通过浏览器HTTP协议传输,禁止其他方式访问。JS引擎就会禁止通过document.cookie获取。

SameSite:防范扩展请求伪造攻击,设置成SameSite=Strict可以严格制定Cookie不能随跳转链接跨站发送,SameSite=Lax则宽松一点,禁止POST跨站。

Secure:表示仅能用HTTPS协议加密传输,明文的HTTP会禁止发送。但Cookie本身不是加密的,浏览器里还是以明文的形式存在。

Cookie的应用

身份识别、广告跟踪。

广告追踪:网站的页面里会嵌入很多广告代码,里面就会访问广告商,在浏览器里存储广告商的cookie。

你换到其他网站,上面也有这个广告商的广告代码,因为都是一个广告商网站,自然就能够读取之前设置的cookie,也就获得了你的信息。

20 | 生鲜速递:HTTP的缓存控制

服务器的缓存控制

1、浏览器发现缓存无数据,于是发送请求,向服务器获取资源。

2、服务器响应请求,返回资源,同事标记资源的有效期。

3、浏览器缓存资源,等待下次重用。

服务器标记资源有效期使用的头字段是Cache-Control,max-age=30即有效时间,此处为缓存30s。此处的30s是从服务器响应报文创建的时刻开始计算而不是客户端收到报文的时刻,也就是说包括了在链路传输过程中所有节点所停留的时间。

max-age的其他值:

no-store:不允许缓存

no-cache:可以缓存,但在使用前必须去服务器验证是否过期,是否有最新版本。

must-revalidate:缓存不过期就可以使用,过期了还想用就得去服务器验证。

客户端的缓存控制

客户端请求头也可以发送一个Cache-Control,服务器看到就会返回一个最新生成的报文回应。

此处表示没有发送请求而是读取磁盘上的缓存,例如我们点击前进或者后退的时候。

条件请求

先发送一个HEAD获取请求的元信息,与缓存作比较,没有改动就用缓存,有改动就再发送请求获取资源。但是网络成本太高。所以有了条件请求。

定义了一系列if开头的条件请求字段,专门用来检查资源是否过期。把两个请求完成的事情交给一个请求完成,让服务器进行验证。

第一次的响应报文先提供Last-modified和ETag,然后第二次请求就会带上缓存里的原值,验证资源是否是最新的。

ETag是一个资源的唯一标识,主要用来解决时间无法准确区分文件变化的问题。

if-Modified-Since

if-None-Match

if-Unmodified

if-Match

if-Range

2、

21 | 良心中间商:HTTP的代理服务

代理的作用

负载均衡 健康检查 安全防护 加密卸载 数据过滤 内容缓存

代理相关字段

Via标明代理的身份

但是Via只是标明是否存在代理的问题。

X-Forwarded-For:和Via类似,只是Via追加的是代理主机名或域名,而X-Forwarded-For则是追加IP地址。

X-Real-IP:X-Forwarded-For的简化版,没有中间的代理信息,直接记录客户端的IP地址。

X-Forwarded-Host:只记录客户端的原始域名

X-Forwarded-Proto:只记录客户端的原始协议名

代理协议

通过X-Forwarded-For,服务器可以拿到客户端的准确信息,但是对于代理服务器来说却不是最佳的解决方案,原本只要转发消息就好,但是通过X-Forwarded-For操作代理信息就必须要解析HTTP报文头,这对于代理来说成本有点高,需要解析数据再修改数据,会降低代理的转发性能。

所以出现了一个代理协议。可以再不改动原始报文的情况下传递客户端的真实IP。 在HTTP报文钱增加了一行ASCLL码文本,以PROXY开头,如下。

PROXY TCP4 1.1.1.1 2.2.2.2 55555 80\r\n
GET / HTTP/1.1\r\n
Host: www.xxx.com\r\n
\r\n

服务器看到这样的报文只要解析第一行就拿到客户端的地址。

22 | 冷链周转:HTTP的缓存代理

缓存代理服务

在没有缓存的时候,代理服务器每次都是直接转发客户端和服务器的报文,中间不会存储任何数据,只有最简单的中转功能。加入缓存后,代理就会把报文存入自己的Cache中。下次有相同的请求就会直接发送304或者缓存数据。

源服务器的缓存控制

private:表示只能在客户端保存

public:表示缓存完全开放、

例如登录操作,服务器会返回Set-Cookie,这种就不能代理,否则就被别人获取登录信息。

must-revalidate:缓存失效后,要求必须回源服务器验证。

proxy-revalidate:缓存失效后,只要求代理的缓存过期后必须验证,客户端只要验证到代理这一步就行。

s-maxage:代理的缓存时间

no-transfoem:代理有时候会对缓存下来的数据做一些优化,该属性则表明禁止这样做。

客户端的缓存控制

max-stale:缓存过期也可以接受,但不能超过x秒

min-fresh:不允许过期并且至少x天后还是新鲜的

其他问题

Vary相当于报文版本的标记,可能会有不同的字符集、编码等,代理上也要存储不同版本。

缓存清理,可以自定义请求方法,发给代理服务器,要求删除URI对应的缓存数据。

安全篇 (7讲)

HTTPS是什么?SSL/TLS又是什么?

因为HTTP是明文传输所以不安全,容易被黑客窃听和篡改。

通信安全必须同时具备机密性、完整性、身份认证和不可否认这个四个特性。

HTTPS的语法、语义仍然是HTTP,但把下层协议由TCP/IP换成了SSL/TLS。

SSL/TSL是信息安全领域中的权威标准,采用多种先进的加密技术保证通信安全。

OpenSSL是著名的开源密码学工具包,是SSL/TSL的具体实现。

固若金汤的根本(上):对称加密与非对称加密

对称加密

非对称加密 混合加密

固若金汤的根本(下):数字签名与证书

黑客虽然拿不到会话密钥,但是可以通过窃听收集足够多的密文,再尝试修改、重组后发送给网站,所以这里还需要使用到数字签名。

数字签名就是非对称加密里面的私钥加上摘要算法,私钥加密,公钥解密。与非对称算法反过来。实现身份认证和不可否认。

数字证书

但是这里还有一个问题就是公钥,如何确保这个公钥是你的公钥而不是黑客仿造的公钥呢?这就存在一个公钥的信任问题。在这里我们通过一个第三方CA,CA将公钥、序列号、用途等等打成一个包再签名,形成数字证书。

公钥的分发需要使用数字证书,必须由CA的信任链来验证,否则就是不可信的。

自签名证书

但CA如何证明自己呢,这就是源源不断的问题,小CA可以找大CA证明,但是链条的最后就只能自己证明自己了,即自签名证书或者根证书。

有了这个证书体系,操作系统和浏览器内置了各大CA的根证书,上网的时候只要服务器发过来它的证书,就可以验证证书里的签名,顺着证书链一层一层的验证,确定公钥是否可信。

我们在实验室用的是野路子的自签名证书,是不被浏览器信任的,但是只要我们把它装进系统的根证书存储区,就会作为信任链的根,就不会再被警告。

但是CA也不一定是完全安全的,因为CA也可能被黑客攻陷等等。解决办法有CRL、OCSP还有终止信任。

信任始于握手:TLS1.2连接过程解析

在HTTPS中,会比HTTP多一个握手过程,在TCP上建立安全连接,之后才是收发报文。

TLS协议的组成

TLS包含几个子协议:记录协议、警报协议、握手协议、变更密码规范协议。

TLS握手过程

HTTP协议会先向服务器执行TCP握手,然后执行TLS握手,才能建立安全连接。

握手的目标是安全的交换对称密钥,需要三个随机数,第三个随机数Pre-Master必须加密传输,决不能让hei ke po jie。 来自评论的总结:

总结下TLS的握手过程:

第一阶段:C/S两端共享Client Random、Server Random 和 Server Params信息 客户端--->服务器: 客户端的版本号、支持的密码套件,还有一个随机数(Client Random)

服务端--->客户端: 客户端的版本号、选择的客户端列表的密码套件如:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384、随机数随机数(Server Random)

服务端--->客户端: 服务端证书(Server Certificate)

服务端--->客户端: 发送Server Key Exchange类型的请求,携带椭圆曲线的公钥(Server Params)用以实现密钥交换算法,另附私钥签名

服务端--->客户端: 发送完毕

第二阶段:证书验证

前验条件:客户端证书链逐级验证、证书公钥验证签名,服务端身份验证成功(证书合法)

客户端--->服务端 发送Client Key Exchange类型的请求,携带椭圆曲线的公钥(Client Params)用以实现秘钥交换算法

第三阶段:主密钥生成

客户端、服务端分别使用Client Params、Server Params通过ECDHE算法计算出随机值pre-master,然后用 Client Random、Server Random 和 Pre-Master三个值作为原材料,用PRF伪随机数函数(利用密码套件的摘要算法再次强化结果 值maser secert的随机性)计算出主密钥Master Secret,

主密钥并不是会话秘钥,还会再用PRF扩展出更多的密钥,比如客户端发送用的会话密钥(client_write_key)、服务器发送用的会话密钥(server_write_key)

客户端--->服务端: 客户端发一个“Change Cipher Spec”,然后再发一个“Finished”消息,把之前所有发送的数据做个摘要,再加密一下,让服务器做个验证.

服务端--->客户端: 服务器也是同样的操作,发“Change Cipher Spec”和“Finished”消息,双方都验证加密解密 OK,握手正式结束.

更好更快的握手:TLS1.3特性解析

TLS1.2已经是2008年的老协议了,在安全性能上已经跟不上现在的互联网了,所以TLS1.3在2018年登场。

连接太慢该怎么办:HTTPS的优化

慢的原因是因为不仅要进行非对称加密握手还要进行握手后对称加密报文传输。

硬件优化

更快的CPU SSL加速卡 SSL加速服务器

软件优化

软件升级 协议优化

证书优化

证书传输 证书验证

会话复用

Session ID 对于千万级访问量用户的服务器来说加重了服务器的负担

会话票证

Session Ticket

预共享密钥

我应该迁移到HTTPS吗?

要 各大浏览器已经开始强推HTTPS等原因

迁移的顾虑

慢 贵 难

现在已经没有那么慢 那么贵了 难点主要是因为涉及很多领域,但是也不是需要全部掌握,抓住少数几个要点就好。如下。

申请证书

配置HTTPS

服务器名称指示

重定向跳转

时代之风(上):HTTP/2特性概览

头部压缩 二进制格式 虚拟的流 强化安全 协议栈

时代之风(下):HTTP/2内核剖析

未来之路:HTTP/3展望

我应该迁移到HTTP/2吗?

Nginx:高性能的Web服务器

OpenResty:更灵活的Web服务器

WAF:保护我们的网络服务

CDN:加速我们的网络服务

WebSocket:沙盒里的TCP

HTTP性能优化面面观(上)

HTTP性能优化面面观(下)