Skip to content

整理自 JavaGuide:原文。全文搬运仅供个人学习,请勿外传。

HTTP 能传输网页内容,但默认是明文传输。请求和响应如果在网络中被监听、篡改或冒充,HTTP 本身没有足够的保护能力。

HTTPS 不是一个全新的应用层协议,而是使用 TLS 保护 HTTP 通信。在 HTTP/1.1 和常见的 HTTP/2 场景中,TLS 通常运行在 TCP 之上;HTTP/3 则把 HTTP 语义映射到基于 UDP 的 QUIC,并在 QUIC 中集成 TLS 1.3。

这篇文章主要回答几个问题:

  1. HTTP 和 HTTPS 的核心区别是什么?
  2. HTTPS 如何防止窃听、篡改和冒充?
  3. SSL/TLS 握手大致做了哪些事情?
  4. 为什么使用 HTTPS 后,证书、混合内容和性能优化仍然需要关注?

HTTP 协议 ​

HTTP 协议介绍 ​

HTTP 协议,全称超文本传输协议(Hypertext Transfer Protocol)。顾名思义,HTTP 协议就是用来规范超文本的传输,超文本,也就是网络上的包括文本在内的各式各样的消息,具体来说,主要是来规范浏览器和服务器端的行为的。

并且,HTTP 是一个无状态(stateless)协议,也就是说服务器不维护任何有关客户端过去所发请求的消息。这其实是一种懒政,有状态协议会更加复杂,需要维护状态(历史信息),而且如果客户或服务器失效,会产生状态的不一致,解决这种不一致的代价更高。

HTTP:超文本传输协议概览

HTTP 协议通信过程 ​

HTTP 是应用层协议。下面以基于 TCP 的 HTTP/1.1 为例说明通信过程,http URL 的默认端口为 80:

  1. 服务器在 80 端口等待客户的请求。
  2. 浏览器发起到服务器的 TCP 连接(创建套接字 Socket)。
  3. 服务器接收来自浏览器的 TCP 连接。
  4. 浏览器(HTTP 客户端)与 Web 服务器(HTTP 服务器)交换 HTTP 消息。
  5. 关闭 TCP 连接。

HTTP 协议优点 ​

扩展性强、速度快、跨平台支持性好。

HTTPS 协议 ​

HTTPS 协议介绍 ​

HTTPS(Hypertext Transfer Protocol Secure)使用 TLS 为 HTTP 提供机密性、完整性和身份认证,默认端口号是 443。HTTP/1.1 和 HTTP/2 通常使用 TLS over TCP;HTTP/3 使用集成 TLS 1.3 的 QUIC,QUIC 构建在 UDP 之上。

HTTPS 中,TLS 握手完成后,通信数据使用 AES-GCM、ChaCha20-Poly1305 等对称 AEAD 算法保护。握手可以使用 (EC)DHE 协商共享秘密,也可以在会话恢复等场景使用 PSK;旧版 TLS 还曾支持 RSA 密钥传输。ECDH/ECDHE 是密钥协商算法,不是使用公钥加密一把预先生成的对称密钥。

HTTPS 协议优点 ​

保密性好、信任度高。

HTTPS 的核心—SSL/TLS 协议 ​

HTTPS 的安全能力来自 TLS。TLS 对通信数据提供机密性和完整性保护,并通过证书等机制认证通信对端。接下来重点介绍 TLS 的工作原理。

SSL 和 TLS 的区别? ​

SSL 和 TLS 没有太大的区别。​

SSL 指安全套接层协议(Secure Sockets Layer),首次发布于 1996 年(SSL 3.0)。SSL 1.0 从未面世,SSL 2.0 则具有较大的缺陷(DROWN 缺陷——Decrypting RSA with Obsolete and Weakened eNcryption)。很快,在 1999 年,SSL 3.0 进一步升级,​新版本被命名为 TLS 1.0​。因此,TLS 是基于 SSL 之上的,但由于习惯叫法,通常把 HTTPS 中的核心加密协议混称为 SSL/TLS。目前 SSL 已完全废弃,TLS 1.2 和 TLS 1.3 是现代 HTTPS 的实际标准。

SSL/TLS 的工作原理 ​

非对称加密 ​

TLS 会使用非对称密码机制完成身份认证和/或密钥协商,再使用对称密钥保护业务数据。非对称密码并不只有“公钥加密、私钥解密”这一种用途:数字签名使用私钥签名、公钥验证,ECDHE 则通过双方的临时密钥协商共享秘密。下面的邮箱比喻只用于说明 RSA 等公钥加密方案的基本概念,不能代表所有 TLS 握手。

在某个自助邮局,每个通信信道都是一个邮箱,每一个邮箱所有者都在旁边立了一个牌子,上面挂着一把钥匙:这是我的公钥,发送者请将信件放入我的邮箱,并用公钥锁好。

但是公钥只能加锁,并不能解锁。解锁只能由邮箱的所有者——因为只有他保存着私钥。

这样,通信信息就不会被其他人截获了,这依赖于私钥的保密性。

非对称加密中公钥加密和私钥解密的过程

非对称加密的公钥和私钥需要采用一种复杂的数学机制生成(密码学认为,为了较高的安全性,尽量不要自己创造加密方案)。公私钥对的生成算法依赖于单向陷门函数。

单向函数:已知单向函数 f,给定任意一个输入 x,易计算输出 y=f(x);而给定一个输出 y,假设存在 f(x)=y,很难根据 f 来计算出 x。

单向陷门函数:一个较弱的单向函数。已知单向陷门函数 f,陷门 h,给定任意一个输入 x,易计算出输出 y=f(x;h);而给定一个输出 y,假设存在 f(x;h)=y,很难根据 f 来计算出 x,但可以根据 f 和 h 来推导出 x。

单向函数

上图就是一个单向函数(不是单项陷门函数),假设有一个绝世秘籍,任何知道了这个秘籍的人都可以把苹果汁榨成苹果,那么这个秘籍就是“陷门”了吧。

在这里,函数 f 的计算方法相当于公钥,陷门 h 相当于私钥。公钥 f 是公开的,任何人对已有输入,都可以用 f 加密,而要想根据加密信息还原出原信息,必须要有私钥才行。

对称加密 ​

TLS 不会使用非对称密码算法直接加密大量业务数据。握手阶段完成身份认证和密钥建立后,记录层使用对称 AEAD 算法保护 HTTP 请求和响应。

对称加密:通信双方共享唯一密钥 k,加解密算法已知,加密方利用密钥 k 加密,解密方利用密钥 k 解密,保密性依赖于密钥 k 的保密性。

对称加密中双方使用共享密钥加密通信

通信双方需要在不安全的网络上建立只有彼此知道的流量密钥。TLS 1.2 的静态 RSA 密钥交换会由客户端生成 PreMasterSecret,再用服务器 RSA 公钥加密发送;现代 TLS 更常使用 ECDHE,让双方交换临时公钥并各自计算出同一个共享秘密。TLS 1.3 已移除静态 RSA 密钥交换,允许 (EC)DHE、PSK 或 PSK+(EC)DHE 等密钥建立方式。无论使用哪种方式,最终都会派生出对称流量密钥来保护后续数据;任何密码方案都不能称为“绝对安全”。

公钥传输的信赖性 ​

SSL/TLS 介绍到这里,了解信息安全的朋友又会想到一个安全隐患。设想下面的场景:

客户端 C 和服务器 S 想要使用 SSL/TLS 通信,由上述 SSL/TLS 通信原理,C 需要先知道 S 的公钥,而 S 公钥的唯一获取途径,就是把 S 公钥在网络信道中传输。要注意网络信道通信中有几个前提:

  1. 任何人都可以捕获通信包
  2. 通信包的保密性由发送者设计
  3. 保密算法设计方案默认为公开,而(解密)密钥默认是安全的

因此,假设 S 公钥不做加密,在信道中传输,那么很有可能存在一个攻击者 A,发送给 C 一个诈包,假装是 S 公钥,其实是诱饵服务器 AS 的公钥。当 C 收获了 AS 的公钥(却以为是 S 的公钥),C 后续就会使用 AS 公钥对数据进行加密,并在公开信道传输,那么 A 将捕获这些加密包,用 AS 的私钥解密,就截获了 C 本要给 S 发送的内容,而 C 和 S 二人全然不知。

同样的,S 公钥即使做加密,也难以避免这种信任性问题,C 被 AS 拐跑了!

中间人替换服务器公钥导致客户端误信攻击者公钥

为了公钥传输的信赖性问题,第三方机构应运而生——证书颁发机构(CA,Certificate Authority)。CA 默认是受信任的第三方。CA 会给各个服务器颁发证书,证书存储在服务器上,并附有 CA 的电子签名​(见下节)。

当服务器使用证书认证时,客户端会获取服务器提供的证书链,并验证签名链是否能连接到本地信任的根,同时检查目标主机名、有效期、密钥用途和路径约束等信息。只有这些检查通过,客户端才能把证书中的公钥与目标服务身份绑定起来。PSK 等不使用证书的认证方式属于另一类场景。

数字签名 ​

好,到这一小节,已经是 SSL/TLS 的尾声了。上一小节提到了数字签名,数字签名要解决的问题,是防止证书被伪造。第三方信赖机构 CA 之所以能被信赖,就是 靠数字签名技术​。

数字签名用于检测证书内容是否被篡改,并证明签名由持有 CA 私钥的一方生成。应当把这个过程描述为“私钥签名、公钥验证”,而不是普遍意义上的“私钥加密、公钥解密”。具体行为如下:

CA 核验申请信息后,使用自己的私钥对证书待签名部分生成数字签名,并把签名附在证书中。

服务器将证书链发送给客户端。客户端使用签发者证书中的公钥验证当前证书的签名,并逐级验证到本地信任的根。

签名验证只是证书验证的一部分。客户端还需要检查目标主机名、有效期、用途、基本约束和名称约束等条件,全部通过后才接受服务器身份。

CA 通过数字签名证明证书未被篡改

总结来说,带有证书的公钥传输机制如下:

  1. 设有服务器 S,客户端 C,和第三方信赖机构 CA。
  2. CA 核验 S 的申请信息,为包含 S 公钥和身份信息的证书生成数字签名。
  3. S 获得 CA 颁发的证书,将该证书传递给 C。
  4. C 获得 S 的证书链,使用各级签发者公钥验证签名,并确认该链最终锚定到本地信任的根。
  5. C 继续检查域名、有效期、用途和证书约束。全部通过后,才接受证书中公钥与目标服务身份的绑定关系。

HTTPS 通过 CA 证书可信传递服务器公钥

对于数字签名,我这里讲的比较简单,如果你没有搞清楚的话,强烈推荐你看看数字签名及数字证书原理这个视频,这是我看过最清晰的讲解。

数字签名及数字证书原理视频讲解截图

总结 ​

  • 端口号​:HTTP 默认是 80,HTTPS 默认是 443。
  • URL 前缀​:HTTP 的 URL 前缀是 http://,HTTPS 的 URL 前缀是 https://。
  • 安全性和传输方式​:未使用 TLS 的 HTTP 默认不提供机密性、完整性和对端身份认证。HTTPS 使用 TLS 保护 HTTP;HTTP/1.1 和 HTTP/2 通常使用 TLS over TCP,HTTP/3 使用集成 TLS 1.3 的 QUIC。TLS 握手负责认证对端并建立流量密钥,后续数据由对称 AEAD 算法保护。证书主要用于身份认证,不能笼统地说“证书加密了对称密钥”。
本文整理自JavaGuide 后端八股的公开内容,仅供个人学习使用

本站仅供个人学习使用,请勿外传