HTTP俯瞰
Web服务器
比起层出不穷的各种 Web 浏览器, Web 服务器就要少很多了,一只手的手指头就可以数 得过来。 Apache 是老牌的服务器,到今天已经快 25 年了,功能相当完善,相关的资料很多,学习 门槛低,是许多创业者建站的入门产品。 Nginx 是 Web 服务器里的后起之秀,特点是高性能、高稳定,且易于扩展。自 2004 年推 出后就不断蚕食 Apache 的市场份额,在高流量的网站里更是不二之选。 此外,还有 Windows 上的 IIS、 Java 的 Jetty/Tomcat 等,因为性能不是很高,所以在互 联网上应用得较少。
CDN
现在互联网中的一项重要基础设施,除了基本的网络加速外,还提供负载均衡、 安全防护、边缘计算、跨运营商网络等功能,能够成倍地“放大”源站服务器的服务能力, 很多云服务商都把 CDN 作为产品的一部分,我也会在后面用一讲的篇幅来专门讲解 CDN。
Web Service
是一种由 W3C 定义的应用服务开发规范,使用 client-server 主从架构,通 常使用 WSDL 定义服务接口,使用 HTTP 协议传输 XML 或 SOAP 消息,也就是说,它是
一个基于 Web(HTTP)的服务架构技术,既可以运行在内网,也可以在适当保护后运行 在外网。
Web Service 是网络服务实体,而 Web Server 是网络服务器,后者的存在 是为了承载前者。
网络七层架构
物理层 链路层 网络层 传输层 会话层 表示层 应用层
可以用口诀来记忆:物联网苏慧试用
SSL 的全称是“Secure Socket Layer”,由网景公司发明,当发展到 3.0 时被标准化,改名为 TLS,即“Transport Layer Security”,但由于历史的原因还是有很多人称之为
SSL/TLS,或者直接简称为 SSL。
代理
代理(Proxy)是 HTTP 协议中请求方和应答方中间的一个环节,作为“中转站”,既可以 转发客户端的请求,也可以转发服务器的应答。 代理有很多的种类,常见的有: 1 . 匿名代理:完全“隐匿”了被代理的机器,外界看到的只是代理服务器; 2. 透明代理:顾名思义,它在传输过程中是“透明开放”的,外界既知道代理,也知道客 户端; 3. 正向代理:靠近客户端,代表客户端向服务器发送请求; 4. 反向代理:靠近服务器端,代表服务器响应客户端的请求;
小结
TCP/IP 是网络世界最常用的协议,HTTP 通常运行在 TCP/IP 提供的可靠传输基础上;
DNS 域名是 IP 地址的等价替代,需要用域名解析实现到 IP 地址的映射;
URI 是用来标记互联网上资源的一个名字,由“协议名 + 主机名 + 路径”构成,俗称
URL;
HTTPS 相当于“HTTP+SSL/TLS+TCP/IP”,为 HTTP 套了一个安全的外壳;
代理是 HTTP 传输过程中的“中转站”,可以实现缓存加速、负载均衡等功能。
操作系统里还有一个特殊的“主机映射”文件,通常是一个可编辑的文本,在 Linux 里是“/etc/hosts”,在 Windows 里 是“C:\WINDOWS\system32\drivers\etc\hosts”,如果操作系统在缓存里找不到 DNS 记录,就会找这个文件。
有了域名,又有了可以稳定工作的解析系统,于是我们就可以实现比 IP 地址更多的“新玩 法”了。 第一种,也是最简单的,“重定向”。因为域名代替了 IP 地址,所以可以让对外服务的域 名不变,而主机的 IP 地址任意变动。当主机有情况需要下线、迁移时,可以更改 DNS 记 录,让域名指向其他的机器。 比如,你有一台“buy.tv”的服务器要临时停机维护,那你就可以通知 DNS 服务器:“我 这个 buy.tv 域名的地址变了啊,原先是 1 .2.3.4,现在是 5.6.7.8,麻烦你改一下。” DNS 于是就修改内部的 IP 地址映射关系,之后再有访问 buy.tv 的请求就不走 1 .2.3.4 这台主 机,改由 5.6.7.8 来处理,这样就可以保证业务服务不中断。
有一些不怀好意的 DNS,那么它也可以在域名这方 面“做手脚”,弄一些比较“恶意”的“玩法”,举两个例子:
域名屏蔽”,对域名直接不解析,返回错误,让你无法拿到 IP 地址,也就无法访问网 站; “域名劫持”,也叫“域名污染”,你要访问 A 网站,但 DNS 给了你 B 网站
DNS
域名使用字符串来代替 IP 地址,方便用户记忆,本质上一个名字空间系统;
DNS 就像是我们现实世界里的电话本、查号台,统管着互联网世界里的所有网站,是一 个“超级大管家”;
DNS 是一个树状的分布式查询系统,但为了提高查询效率,外围有多级的缓存;
使用 DNS 可以实现基于域名的负载均衡,既可以在内网,也可以在外网。
访问一个网站的过程
假设你要访问的是 Apple 网站,显然你是不知道它的真实 IP 地址的,在浏览器里只能使用 域名“www.apple.com”访问,那么接下来要做的必然是域名解析。这就要用 DNS 协议 开始从操作系统、本地 DNS、根 DNS、顶级 DNS、权威 DNS 的层层解析,当然这中间 有缓存,可能不会费太多时间就能拿到结果。
目前 HTTP/1 .1 规定了八种方法,单词都必须是大写的形 式,我先简单地列把它们列出来,后面再详细讲解。
GET:获取资源,可以理解为读取或者下载数据;
HEAD:获取资源的元信息;
POST:向资源提交数据,相当于写入或上传数据;
PUT:类似 POST;
DELETE:删除资源;
CONNECT:建立特殊的连接隧道;
OPTIONS:列出可对资源实行的方法;
TRACE:追踪请求 - 响应的传输路径。
既然请求方法是一个“指示”,那么客户端自然就没有决定权,服务器掌控着所有资源,也就有绝对的决策权力。它收到 HTTP 请求报文后,看到里面的请求方法,可以执行也可以拒绝,或者改变动作的含义,毕竟 HTTP 是一个“协
议”,两边都要“商量着来”。
比如,你发起了一个 GET 请求,想获取“/orders”这个文件,但这个文件保密级别比较高,不是谁都能看的,服务器就可以有如下的几种响应方式:
假装这个文件不存在,直接返回一个 404 Not found 报
文;
稍微友好一点,明确告诉你有这个文件,但不允许访问,
返回一个 403 Forbidden;
再宽松一些,返回 405 Method Not Allowed,然后用
Allow 头告诉你可以用 HEAD 方法获取文件的元信息。
元信息
HEAD方法与 GET 方法类似,也是请求从服务器获取资
源,服务器的处理机制也是一样的,但服务器不会返回请求的实体数据,只会传回响应头,也就是资源的“元信息”。
HEAD 方法可以看做是 GET 方法的一个“简化版”或
者“轻量版”。因为它的响应头与 GET 完全相同,所以可以用在很多并不真正需要资源的场合,避免传输 body 数据的浪费。
比如,想要检查一个文件是否存在,只要发个 HEAD 请求就可以了,没有必要用 GET 把整个文件都取下来。再比
如,要检查文件是否有最新版本,同样也应该用 HEAD,服务器会在响应头里把文件的修改时间传回来。
PUT 和 POST的微妙关系
PUT 的作用与 POST 类似,也可以向服务器提交数据,但与 POST 存在微妙的不同,通常 POST 表示的是“新
建”“create”的含义,而 PUT 则是“修
改”“update”的含义。
GET 和 HEAD 既是安全的也是幂等的,DELETE
可以多次删除同一个资源,效果都是“资源不存在”,所以也是幂等的。
POST 和 PUT 的幂等性质就略费解一点。
按照 RFC 里的语义,POST 是“新增或提交数据”,多次提交数据会创建多个资源,所以不是幂等的;而 PUT
是“替换或更新数据”,多次更新一个资源,资源还是会第一次更新的状态,所以是幂等的。
如何拼写一个网址
URI的组成
不过必须要说的是,URI 还有一个“真正”的完整形态,如下图所示。
URI编码
刚才我们看到了,在 URI 里只能使用 ASCII 码,但如果要 在 URI 里使用英语以外的汉语、日语等其他语言该怎么办 呢? 还有,某些特殊的 URI,会在 path、 query 里出 现“@&?"等起界定符作用的字符,会导致 URI 解析错误, 这时又该怎么办呢? 所以, URI 引入了编码机制,对于 ASCII 码以外的字符集和 特殊字符做一个特殊的操作,把它们转换成与 URI 语义不冲 突的形式。这在 RFC 规范里称 为“escape”和“unescape”,俗称“转义”。
URI 转义的规则有点“简单粗暴”,直接把非 ASCII 码或特 殊字符转换成十六进制字节值,然后前面再加上一 个“%”。 例如,空格被转义成“%20”,“?”被转义成“%3F”。 而中文、日文等则通常使用 UTF-8 编码后再转义,例如“银河”会被转义成“%E9%93%B6%E6%B2%B3”有了这个编码规则后, URI 就更加完美了,可以支持任意的 字符集用任何语言来标记资源。
HTTP特点
可靠
因为 HTTP 协议是基于 TCP/IP 的,而 TCP 本身是一个“可靠”的传 输协议,所以 HTTP 自然也就继承了这个特性,能够在请求方和应答方之间“可靠”地传 输数据。 它的具体做法与 TCP/UDP 差不多,都是对实际传输的数据( entity)做了一层包装,加上 一个头,然后调用 Socket API,通过 TCP/IP 协议栈发送或者接收。 不过我们必须正确地理解“可靠”的含义, HTTP 并不能 1 00% 保证数据一定能够发送到 另一端,在网络繁忙、连接质量差等恶劣的环境下,也有可能收发失败。“可靠”只是向使 用者提供了一个“承诺”,会在下层用多种手段“尽量”保证数据的完整送达。
应用层协议
在 TCP/IP 诞生后的几十年里,虽然出现了许多的应用层协议,但它们都仅关注很小的应用 领域,局限在很少的应用场景。例如 FTP 只能传输文件、 SMTP 只能发送邮件、 SSH 只能 远程登录等,在通用的数据传输方面“完全不能打”。 所以 HTTP 凭借着可携带任意头字段和实体数据的报文结构,以及连接控制、缓存代理等 方便易用的特性,一出现就“技压群雄”,迅速成为了应用层里的“明星”协议。只要不太 苛求性能, HTTP 几乎可以传递一切东西,满足各种需求,称得上是一个“万能”的协议。
套用一个网上流行的段子,HTTP 完全可以用开玩笑的口吻说:“不要误会,我不是针对FTP,我是说在座的应用层各位,都是垃圾。
小结
-
HTTP 是灵活可扩展的,可以任意添加头字段实现任意功能;
-
HTTP 是可靠传输协议,基于 TCP/IP 协议“尽量”保证数据的送达;
-
HTTP 是应用层协议,比 FTP、SSH 等更通用功能更多,能够传输任意数据;
-
HTTP 使用了请求 - 应答模式,客户端主动发起请求,服务器被动回复请求;
-
HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或
服务器记录请求相关的信息。
有了范围请求之后, HTTP 处理大文件就更加轻松了,看视 频时可以根据时间点计算出文件的 Range,不用下载整个 文件,直接精确获取片段所在的数据内容。 不仅看视频的拖拽进度需要范围请求,常用的下载工具里的 多段下载、断点续传也是基于它实现的,要点是:
先发个 HEAD,看服务器是否支持范围请求,同时获取文 件的大小; 开 N 个线程,每个线程使用 Range 字段划分出各自负责 下载的片段,发请求传输数据; 下载意外中断也不怕,不必重头再来一遍,只要根据上次 的下载记录,用 Range 请求剩下的那一部分就可以了。
1.压缩 HTML 等文本文件是传输大文件最基本的方法;
-
分块传输可以流式收发数据,节约内存和带宽,使用响应 头字段“Transfer-Encoding: chunked”来表示,分块 的格式是 1 6 进制长度头 + 数据块;
-
范围请求可以只获取部分数据,即“分块请求”,实现视 频拖拽或者断点续传,使用请求头字段“Range”和响应 头字段“Content-Range”,响应状态码必须是 206;
-
也可以一次请求多个范围,这时候响应报文的数据类型 是“multipart/byteranges”, body 里的多个部分会用 boundary 字符串分隔。
TCP 建立连接要有“三 次握手”,发送 3 个数据包,需要 1 个 RTT;关闭连接 是“四次挥手”, 4 个数据包需要 2 个 RTT。 而 HTTP 的一次简单“请求 - 响应”通常只需要 4 个包, 如果不算服务器内部的处理时间,最多是 2 个 RTT。这么算下来,浪费的时间就是“3÷ 5=60%”,有三分之二的时间 被浪费掉了,传输效率低得惊人。
请求头里明确地要求使用长连接机制,使用的字段是Connection,值是“keep-alive”。
在客户端,可以在请求头里加上“Connection: close”字 段,告诉服务器:“这次通信后就关闭连接”。服务器看到 这个字段,就知道客户端要主动关闭连接,于是在响应报文 里也加上这个字段,发送之后就调用 Socket API 关闭 TCP 连接。
1.早期的 HTTP 协议使用短连接,收到响应后就立即关闭 连接,效率很低;
-
HTTP/1 .1 默认启用长连接,在一个连接上收发多个请求 响应,提高了传输效率;
-
服务器会发送“Connection: keep-alive”字段表示启用 了长连接;
-
报文头里如果有“Connection: close”就意味着长连接 即将关闭;
-
过多的长连接会占用服务器资源,所以服务器会用一些策 略有选择地关闭长连接;
-
“队头阻塞”问题会导致性能下降,可以用“并发连 接”和“域名分片”技术缓解。
URI 发起一个新的 HTTP 请求,获取响应报文后 就会切换显示内容,渲染出新 URI 指向的页面。
1 http : //nginx . org/en/download . html
复制代码
这样的跳转动作是由浏览器的使用者主动发起的,可以称 为“主动跳转”,但还有一类跳转是由服务器来发起的,浏 览器使用者无法控制,相对地就可以称为“被动跳转”,这 在 HTTP 协议里有个专门的名词,叫做“重定 向”
两种URI
"绝对 URI”,就是完整形式的 URI,包括 scheme、host:port、path 等。所谓“相对 URI”,就是省略了 scheme 和 host:port,只有 path 和 query 部
分,是不完整的,但可以从请求上下文里计算得到。
HTTP 是“无状态”的,这既是优点也是缺点。优 点是服务器没有状态差异,可以很容易地组成集群,而缺点就是无法支持需要记录状态的事 务操作。 好在 HTTP 协议是可扩展的,后来发明的 Cookie 技术,给 HTTP 增加了“记忆能力”。
Cookie
Cookie 的工作过程
那么, Cookie 这张小纸条是怎么传递的呢?
这要用到两个字段:响应头字段Set-Cookie和请求头字段Cookie。 当用户通过浏览器第一次访问服务器的时候,服务器肯定是不知道他的身份的。所以,就要 创建一个独特的身份标识数据,格式是“key=value”,然后放进 Set-Cookie 字段里, 随着响应报文一同发给浏览器。 浏览器收到响应报文,看到里面有 Set-Cookie,知道这是服务器给的身份标识,于是就保 存起来,下次再请求的时候就自动把这个值放进 Cookie 字段里发给服务器。 因为第二次请求里面有了 Cookie 字段,服务器就知道这个用户不是新人,之前来过,就可 以拿出 Cookie 里的值,识别出用户的身份,然后提供个性化的服务。
HTTP的缓存
缓存是优化系统性能的重要手段, HTTP 传输的每一个环节中都可以有缓存;
\2. 服务器使用“Cache-Control”设置缓存策略,常用的是“max-age”,表示资源的有 效期;
\3. 浏览器收到数据就会存入缓存,如果没过期就可以直接使用,过期就要去服务器验证是 否仍然可用;
\4. 验证资源是否失效需要使用“条件请求”,常用的是“if-Modified-Since”和“IfNone-Match”,收到 304 就可以复用缓存里的资源;
\5. 验证资源是否被修改的条件有两个:“Last-modified”和“ETag”,需要服务器预先 在响应报文里设置,搭配条件请求使用;
\6. 浏览器也可以发送“Cache-Control”字段,使用“max-age=0”或“no_cache”刷 新数据。
服务代理
匿名代理、透明代理、正向代理和反 向代理
1.HTTP 代理就是客户端和服务器通信链路中的一个中间环节,为两端提供“代理服
务”;
- 代理处于中间层,为 HTTP 处理增加了更多的灵活性,可以实现负载均衡、安全防护、
数据过滤等功能;
-
代理服务器需要使用字段“Via”标记自己的身份,多个代理会形成一个列表;
-
如果想要知道客户端的真实 IP 地址,可以使用字段“X-Forwarded-For”和“X-Real-
IP”;
- 专门的“代理协议”可以在不改动原始报文的情况下传递客户端的真实 IP。
常见代理属性no-transform
代理专用的属性“no-transform”。代理有时候会对缓存下来的数据做一些优 化,比如把图片生成 png、 webp 等几种格式,方便今后的请求处理,而“notransform”就会禁止这样做,不许“偷偷摸摸搞小动作”。
小结
计算机领域里最常用的性能优化手段是“时空转换”,也就是“时间换空间”或者“空
间换时间”,HTTP 缓存属于后者;
缓存代理是增加了缓存功能的代理服务,缓存源服务器的数据,分发给下游的客户端;
“Cache-Control”字段也可以控制缓存代理,常用的有“private”“s-
maxage”“no-transform”等,同样必须配合“Last-modified”“ETag”等字段才
能使用;
缓存代理有时候也会带来负面影响,缓存不良数据,需要及时刷新或删除。
HTTP的安全性
结论——HTTP“不安全”
那什么样的通信过程才是安全的呢? 通常认为,如果通信过程具备了四个特性,就可以认为是“安全”的,这四个特性是:机密 性、完整性,身份认证和不可否认。
机密性( Secrecy/Confidentiality)是指对数据的“保密”,只能由可信的人访问,对其 他人是不可见的“秘密”,简单来说就是不能让不相关的人看到不该看的东西。 比如小明和小红私下聊天,但“隔墙有耳”,被小强在旁边的房间里全偷听到了,这就是没 有机密性。我们之前一直用的 Wireshark ,实际上也是利用了 HTTP 的这个特点,捕获了 传输过程中的所有数据。
完整性( Integrity,也叫一致性)是指数据在传输过程中没有被窜改,不多也不少,“完 完整整”地保持着原状
机密性虽然可以让数据成为“秘密”,但不能防止黑客对数据的修改,黑客可以替换数据, 调整数据的顺序,或者增加、删除部分数据,破坏通信过程。 比如,小明给小红写了张纸条:“明天公园见”。小强把“公园”划掉,模仿小明的笔迹把 这句话改成了“明天广场见”。小红收到后无法验证完整性,信以为真,第二天的约会就告 吹了。
身份认证( Authentication)是指确认对方的真实身份,也就是“证明你真的是你”,保 证消息只能发送给可信的人。 如果通信时另一方是假冒的网站,那么数据再保密也没有用,黑客完全可以使用冒充的身 份“套”出各种信息,加密和没加密一样。 比如,小明给小红写了封情书:“我喜欢你”,但不留心发给了小强。小强将错就错,假冒 小红回复了一个“白日做梦”,小明不知道这其实是小强的话,误以为是小红的,后果可想 而知。 第四个特性是不可否认( Non-repudiation/Undeniable),也叫不可抵赖,意思是不能否 认已经发生过的行为,不能“说话不算数”“耍赖皮”。 使用前三个特性,可以解决安全通信的大部分问题,但如果缺了不可否认,那通信的事务真 实性就得不到保证,有可能出现“老赖”。 比如,小明借了小红一千元,没写借条,第二天矢口否认,小红也确实拿不出借钱的证据, 只能认倒霉。另一种情况是小明借钱后还了小红,但没写收条,小红于是不承认小明还钱的 事,说根本没还,要小明再掏出一千元。 所以,只有同时具备了机密性、完整性、身份认证、不可否认这四个特性,通信双方的利益 才能有保障,才能算得上是真正的安全。
HTTP VS HTTPS
区别:看起来几乎没有大区别,就是有无s。
但底层有了很大的变化。
HTTPS 与 HTTP 最大的区别,它能够鉴别危险的网站,并且尽最大可能保证你的上 网安全,防御黑客对信息的窃听、窜改或者“钓鱼”、伪造。 你可能要问了,既然没有新东西, HTTPS 凭什么就能做到机密性、完整性这些安全特性 呢? 秘密就在于 HTTPS 名字里的“S”,它把 HTTP 下层的传输协议由 TCP/IP 换成了 SSL/TLS,由“HTTP over TCP/IP”变成了“HTTP over SSL/TLS”,让 HTTP 运行在 了安全的 SSL/TLS 协议上(可参考第 4 讲和第 5 讲),收发报文不再使用 Socket API, 而是调用专门的安全接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hSvdfko-1661069385993)(F:\java资源\time.geekbang.org\052罗剑锋-透视HTTP协议(完结)\笔记\初探HTTP.assets\image-20220818174248267.png)]
所以说, HTTPS 本身并没有什么“惊世骇俗”的本事,全是靠着后面的 SSL/TLS“撑 腰”。只要学会了 SSL/TLS, HTTPS 自然就“手到擒来”。
TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成, 综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。 浏览器和服务器在使用 TLS 建立连接时需要选择一组恰当的加密算法来实现安全通信,这 些算法的组合被称为“密码套件”( cipher suite,也叫加密套件)。
说到 TLS,就不能不谈到 OpenSSL,它是一个著名的开源密码学程序库和工具包,几乎支 持所有公开的加密算法和协议,已经成为了事实上的标准,许多应用软件都会使用它作为底 层库来实现 TLS 功能,包括常用的 Web 服务器 Apache、 Nginx 等。 OpenSSL 是从另一个开源库 SSLeay 发展出来的,曾经考虑命名为“OpenTLS”,但当时 ( 1 998 年) TLS 还未正式确立,而 SSL 早已广为人知,所以最终使用了“OpenSSL”的 名字。 OpenSSL 目前有三个主要的分支, 1 .0.2 和 1 .1 .0 都将在今年( 201 9)年底不再维护,最 新的长期支持版本是 1 .1 .1,我们的实验环境使用的 OpenSSL 是“1 .1 .0j”。 由于 OpenSSL 是开源的,所以它还有一些代码分支,比如 Google 的 BoringSSL、 OpenBSD 的 LibreSSL,这些分支在 OpenSSL 的基础上删除了一些老旧代码,也增加了 一些新特性,虽然背后有“大金主”,但离取代 OpenSSL 还差得很远。
小结
-
因为 HTTP 是明文传输,所以不安全,容易被黑客窃听或窜改;
-
通信安全必须同时具备机密性、完整性,身份认证和不可否认这四个特性;
-
HTTPS 的语法、语义仍然是 HTTP,但把下层的协议由 TCP/IP 换成了 SSL/TLS;
-
SSL/TLS 是信息安全领域中的权威标准,采用多种先进的加密技术保证通信安全;
-
OpenSSL 是著名的开源密码学工具包,是 SSL/TLS 的具体实现
摘要算法
实现完整性的手段主要是摘要算法( Digest Algorithm),也就是常说的散列函数、哈希 函数( Hash Function)。 你可以把摘要算法近似地理解成一种特殊的压缩算法,它能够把任意长度的数据“压缩”成 固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指 纹”。 换一个角度,也可以把摘要算法理解成特殊的“单向”加密算法,它只有算法,没有密钥, 加密后的数据无法解密,不能从摘要逆推出原文。
摘要算法实际上是把数据从一个“大空间”映射到了“小空间”,所以就存在“冲 突”( collision,也叫碰撞)的可能性,就如同现实中的指纹一样,可能会有两份不同的原 文对应相同的摘要。好的摘要算法必须能够“抵抗冲突”,让这种可能性尽量地小。 因为摘要算法对输入具有“单向性”和“雪崩效应”,输入的微小不同会导致输出的剧烈变 化,所以也被 TLS 用来生成伪随机数( PRF, pseudo random function)。 你一定在日常工作中听过、或者用过 MD5( Message-Digest 5)、 SHA-1( Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成 1 6 字节和 20 字节长度 的数字摘要。但这两个算法的安全强度比较低,不够安全,在 TLS 里已经被禁止使用了。 目前 TLS 推荐使用的是 SHA-1 的后继者: SHA-2。SHA-2 实际上是一系列摘要算法的统称,总共有 6 种,常用的有 SHA224、 SHA256、 SHA384,分别能够生成 28 字节、 32 字节、 48 字节的摘要。
TLS的历史版本号
TSL1.1
TSL1.2
TSL1.3(2018)
TLS1 .2 在十来年的应用中获得了许多宝贵的经验,陆续发现了很多的漏洞和加密算法的弱 点,所以 TLS1 .3 就在协议里修补了这些不安全因素。 比如: 经过这一番“减肥瘦身”之后, TLS1 .3 里只保留了 AES、 ChaCha20 对称加密算法,分组 模式只能用 AEAD 的 GCM、 CCM 和 Poly1 305,摘要算法只能用 SHA256、 SHA384, 密钥交换算法只有 ECDHE 和 DHE,椭圆曲线也被“砍”到只剩 P-256 和 x2551 9 等 5 种。 减肥可以让人变得更轻巧灵活, TLS 也是这样。 算法精简后带来了一个意料之中的好处:原来众多的算法、参数组合导致密码套件非常复 杂,难以选择,而现在的 TLS1 .3 里只有 5 个套件,无论是客户端还是服务器都不会再 犯“选择困难症”了。 伪随机数函数由 PRF 升级为 HKDF( HMAC-based Extract-and-Expand Key Derivation Function);
明确禁止在记录协议里使用压缩;
废除了 RC4、 DES 对称加密算法;
废除了 ECB、 CBC 等传统分组模式;
废除了 MD5、 SHA1、 SHA-224 摘要算法;
废除了 RSA、 DH 密钥交换算法和许多命名曲线
经过这一番“减肥瘦身”之后, TLS1 .3 里只保留了 AES、 ChaCha20 对称加密算法,分组 模式只能用 AEAD 的 GCM、 CCM 和 Poly1 305,摘要算法只能用 SHA256、 SHA384, 密钥交换算法只有 ECDHE 和 DHE,椭圆曲线也被“砍”到只剩 P-256 和 x2551 9 等 5 种。 减肥可以让人变得更轻巧灵活, TLS 也是这样。 算法精简后带来了一个意料之中的好处:原来众多的算法、参数组合导致密码套件非常复 杂,难以选择,而现在的 TLS1 .3 里只有 5 个套件,无论是客户端还是服务器都不会再 犯“选择困难症”了。
. 为了兼容 1 .1、 1 .2 等“老”协议, TLS1 .3 会“伪装”成 TLS1 .2,新特性在“扩展”里 实现;
\2. 1 .1、 1 .2 在实践中发现了很多安全隐患,所以 TLS1 .3 大幅度删减了加密算法,只保留了 ECDHE、 AES、 ChaCha20、 SHA-2 等极少数算法,强化了安全;
\3. TLS1 .3 也简化了握手过程,完全握手只需要一个消息往返,提升了性能。
HTTPS慢
你可能或多或少听别人说过,“HTTPS 的连接很慢”。那么“慢”的原因是什么呢? 通过前两讲的学习,你可以看到, HTTPS 连接大致上可以划分为两个部分,第一个是建立 连接时的非对称加密握手,第二个是握手后的对称加密报文传输。 由于目前流行的 AES、 ChaCha20 性能都很好,还有硬件优化,报文传输的性能损耗可以 说是非常地小,小到几乎可以忽略不计了。所以,通常所说的“HTTPS 连接慢”指的就是 刚开始建立连接的那段时间。 在 TCP 建连之后,正式数据传输之前, HTTPS 比 HTTP 增加了一个 TLS 握手的步骤,这 个步骤最长可以花费两个消息往返,也就是 2-RTT。而且在握手消息的网络耗时之外,还 会有其他的一些“隐形”消耗,比如:
产生用于密钥交换的临时公私钥对( ECDHE); 验证证书时访问 CA 获取 CRL 或者 OCSP; 非对称加密解密处理“Pre-Master”。
优化HTTPS
硬件优化、软件优化、协议优化、证书优化
如何优化? 硬件优化、软件优化、协议优化、证书优化
硬件优化,说白了就是“花钱”。但花钱也是有门道的,要“有钱用在刀刃上”,不能大把 的银子撒出去“只听见响”。 HTTPS 连接是计算密集型,而不是 I/O 密集型。所以,如果你花大价钱去买网卡、带宽、 SSD 存储就是“南辕北辙”了,起不到优化的效果。 那该用什么样的硬件来做优化呢? 首先,你可以选择更快的 CPU,最好还内建 AES 优化,这样即可以加速握手,也可以加速 传输。 其次,你可以选择“SSL 加速卡”,加解密时调用它的 API,让专门的硬件来做非对称加解 密,分担 CPU 的计算压力。
软件优化
不过硬件优化方式中除了 CPU,其他的通常可不是靠简单花钱就能买到的,还要有一些开 发适配工作,有一定的实施难度。比如,“加速服务器”中关键的一点是通信必须是“异 步”的,不能阻塞应用服务器,否则加速就没有意义了。 所以,软件优化的方式相对来说更可行一些,性价比高,能够“少花钱,多办事”。 软件方面的优化还可以再分成两部分:一个是软件升级,一个是协议优化。
非对称加密解密处理“Pre-Master”。
优化HTTPS
硬件优化,说白了就是“花钱”。但花钱也是有门道的,要“有钱用在刀刃上”,不能大把 的银子撒出去“只听见响”。 HTTPS 连接是计算密集型,而不是 I/O 密集型。所以,如果你花大价钱去买网卡、带宽、 SSD 存储就是“南辕北辙”了,起不到优化的效果。 那该用什么样的硬件来做优化呢? 首先,你可以选择更快的 CPU,最好还内建 AES 优化,这样即可以加速握手,也可以加速 传输。 其次,你可以选择“SSL 加速卡”,加解密时调用它的 API,让专门的硬件来做非对称加解 密,分担 CPU 的计算压力。
软件优化
不过硬件优化方式中除了 CPU,其他的通常可不是靠简单花钱就能买到的,还要有一些开 发适配工作,有一定的实施难度。比如,“加速服务器”中关键的一点是通信必须是“异 步”的,不能阻塞应用服务器,否则加速就没有意义了。 所以,软件优化的方式相对来说更可行一些,性价比高,能够“少花钱,多办事”。 软件方面的优化还可以再分成两部分:一个是软件升级,一个是协议优化。
软件升级实施起来比较简单,就是把现在正在使用的软件尽量升级到最新版本,比如把 Linux 内核由 2.x 升级到 4.x,把 Nginx 由 1 .6 升级到 1 .1 6,把 OpenSSL 由 1 .0.1 升级到 1 .1 .0/1 .1 .1。 由于这些软件在更新版本的时候都会做性能优化、修复错误,只要运维能够主动配合,这种 软件优化是最容易做的,也是最容易达成优化效果的。 但对于很多大中型公司来说,硬件升级或软件升级都是个棘手的问题,有成千上万台各种型 号的机器遍布各个机房,逐一升级不仅需要大量人手,而且有较高的风险,可能会影响正常 的线上服务。 所以,在软硬件升级都不可行的情况下,我们最常用的优化方式就是在现有的环境下挖掘协 议自身的潜力