前言:

最近在重新找工作,很幸运我遇到了我觉得非常棒的面试,虽然我回答的一塌糊涂,但让我发现了自己原来有很多不足之处,觉得跳出舒适圈是一个无比正确的选择。

所以准备,以我个人的理解记录下一些我遇到的觉得比较重要的知识点。

HTTPS/HTTP 对于 Web 开发来说是经常打交道的东西了,但是我对它的理解依然停留在会用、HTTPS 是在 HTTP 的基础上增加了 SSL 证书加密,比 HTTP 要安全。

但是为什么 HTTPS 比 HTTP 多了 SSL 证书加密就比 HTTP 要安全?

#HTTP理解 HTTPS 之前需要先理解下 HTTP,详细内容参考 HTTP 概述。

简单来说,HTTP 就是一种基于 TCP 的应用层传输协议,是用户用来直接访问资源的协议。

TCP 是传输层的协议,传输层的协议最常用的就是 TCP 和 UDP 了,绝大多数 HTTP 都是基于 TCP 协议的,因为 TCP 更加可靠, 更可靠的原因,就是俗称的三次握手的机制。

三次握手再通俗易懂的来讲就是两个人打电话:

客户端:“喂,听得到吗?”(SYN=1 + 随机序列号 seq=x)服务器:“听得到!你能听到我吗?”(SYN=1 + ACK=1 + 随机序列号 seq=y + 确认号 ack=x+1)客户端:“能听到!”(ACK=1 + 序列号 seq=x+1 + 确认号 ack=y+1)

—— 此时双方确认通信畅通,开始正式对话。#HTTPS虽然 TCP 的协议很可靠,但是 HTTP 的数据是以明文传输的,存在数据被监听篡改的风险,这也是 HTTPS 被提出的原因。

HTTPS 并不是一个单独的协议,它是在 HTTP 的基础上,用上了 TLS/SSL建立加密通道进行加密。

所以要搞懂 HTTPS 为什么比 HTTP 安全,其实就是只要搞懂 TLS/SSL就行。

#TLS其实 SSL 就是 TLS 的前身,两种都是一种加密安全协议,而现代浏览器已经全面不支持 SSL 了,只支持 TLS,之所以现在还能看到 SSL 的名字,只是因为它的名声比较大,经常以 TSL/SSL 传播出现而已。

#对称加密对称加密是一种非常常见的加密方式,发送方与接收方约定一种加密算法,搭配上秘钥,将数据以加密后的方式传输,接收方收到加密数据后,只需要用加密算法和秘钥解开就可以获取到数据原文了。

但问题也很明显,第三方如果知道了加密算法和秘钥,那一样可以监听篡改数据传输。

#非对称加密非对称加密则是将秘钥变成公钥和私钥一对秘钥对,通过公钥加密的数据,只能用私钥解密解开。

但这是一种单程加密方式,如果要让 HTTP 用上这种加密方式,那就需要客户端与服务器,各自准备一对自己的秘钥对,在数据正式传输之前,先交换双方公钥,用对方的公钥加密数据在传输即可。

但这种方法缺点就是非对称加密算法非常消耗性能,访问服务器的不只是一个浏览器,当有大量的服务器去请求服务器的时候服务器需要处理大量加密解密工作,对服务器负载太高,会导致网页渲染卡顿。

#非对称与对称加密结合非对称加密会导致服务器负载过高,而对称加密又不够安全,那就结合两套加密方案:

在正式传输数据之前服务器将**非对称加密的公钥**传给浏览器。浏览器使用**非对称加密的公钥来对后面要使用的对称加密的秘钥进行加密,传回给服务器,这样服务器就能用自己的非对称加密私钥进行解密,获取对称加密的秘钥**。浏览器与服务器使用**对称加密的秘钥**进行加密通信。但这种方案也有个问题,对称加密的秘钥是客户端随机生成的随机数,是随机数就有可能猜测出来。所以为了进一步提高随机数秘钥的安全性,对随机数生成增加了以下步骤:

在正式传输数据前,浏览器生成一个**随机数**发送给服务器。服务器收到后,生成第二个**随机数**返回给浏览器。服务器发送**非对称加密的公钥**给浏览器。浏览器在收到随机数和**非对称加密的公钥后,生成第三个随机数,用非对称加密的公钥**加密后发送给服务器。浏览器根据三个随机数生成**秘钥**,并用来加密发送 Finished 消息。服务器据三个随机数生成**秘钥**,并用来加密发送 Finished 消息。浏览器与浏览器双向验证完成后,开始应用数据加密传输。但是这样依然还是不够安全,只要有人冒充服务器,例如取一个服务器地址很近似的地址,这在早期网络还不够发达的时候很容易有人输错地址,这样就夹在浏览器与服务器之间一样可以进行以上的步骤,这就是所谓的中间人攻击。

打个比方就是,你寄快递给你朋友,上门取件的快递员是骗子冒充的。

#SSL 证书其实解决中间人攻击的本质就是信任问题。

现在生活中几乎是已经遇不到骗子冒充快递员上门取件的情况了,因为我们都开始信任了这些快递公司,快递公司也提供取件码等方式让我们去验证快递员的身份。

那换到网络中,我们就一样需要找个类似快递公司可信任的第三方来作为公证了。

首先这个第三方公证人,需要准备一对非对称加密秘钥,并公开他的公钥。服务器将自己的公钥、地址、域名、名字等信息交给第三方公证人。第三方公证人根据服务器提供的信息计算出一个 HASH 值,用自己的私钥对其进行加密,得到了数字签名。将数字签名与服务器提供的信息合在一起作为数字证书,也就是我们所说的 SSL 证书,提供给服务器。浏览器在访问服务器时,服务器需要提供证书进行验证:

对证书中的服务器信息进行摘要计算出一个 HASH 值。使用第三方公证人公钥计算数字签名算出一个 HASH 值。判断两个 HASH 值是否相等:

若相等,则认证通过。若不相等,则认证失败。这套加密方案在早期互联网得到高度认可,第三方公证人也发展成了一个机构,也就是我们所说的 CA 机构(Certificate Authority,证书颁发机构)。

现在 CA 机构非常多,发展成了上下级的关系,也不可避免的出现一些假证书,这就是为什么有些网站明明是 HTTPS 的,但浏览器却提示不安全的原因。

所以为了进一步提高安全性,所有的一级CA 机构也会给自己做一个证书,也就是所谓的根证书,存放在我们的操作系统中。

这样我们以后每当浏览器验证一个服务器证书的时候,会先验证证书的签发者,一直往签发者上级验证,直到最终的签发者在系统的根证书列表中,就表明该证书是可信任的。

#HTTPS 现在还足够安全吗?既然都了解完 HTTPS 发展历史了,那就干脆再深入了解下,现在的 HTTPS 还足够安全吗?

HTTPS 安全的根基还是信任问题,既然是信任问题那就不可能是绝对安全的。

2023 年 DigiCert 次级 CA 事件,因为颁发证书流程错误,需要吊销 0.4% 的证书,这就是一场信任危机。通过一些现实手段,在用户电脑的根证书列表中安装假的根证书,依然可以实现中间人攻击。用户首次访问时若输入 http:// 或裸域名,攻击者可拦截 HTTP 请求并阻止跳转到 HTTPS,强制降级为明文传输,这种攻击方式被称为首次连接劫持(SSL Stripping)。以上方式依然表明 HTTPS 不是绝对安全的。

在写这篇文章制作流程图的时候,发现 Figma 的网络安全上采用 HSTS。

HSTS 通过响应头 Strict-Transport-Security 强制浏览器全链路使用 HTTPS,这样做的好处是:

根除 SSL Stripping:攻击者无法阻止 HTTP 到 HTTPS 的跳转,因为浏览器直接跳过 HTTP 请求。阻止证书警告绕过:若遭遇无效证书(如自签名攻击),浏览器直接阻断连接,用户无法手动“忽略风险”。降低中间人攻击面:子域名(如 cdn.example.com)同样受保护,避免通过次级入口渗透。截止目前为止,采用 **HTTPS + HSTS ** 覆盖超过 150 万域名,但这样依然存在上述所说的安全风险。

虽然 HTTPS 不是绝对安全,但它依然是 Web 开发中的安全必要条件。