深入理解 SSL、TLS 与 HTTPS
1. 核心概念与关系
1.1 课程引言
- 定位: 选修内容,主要应对面试中可能出现的网络安全原理问题,尤其针对校招。
- 关联性:
- 与日常编码(如 Ajax)无直接关系。
- 属于原理层面,与运维和计算机基础知识(网络协议)关系更紧密。
- 直观区别:
- HTTP: 浏览器地址栏显示 "不安全"。
- HTTPS: 浏览器地址栏显示 "一把锁",代表安全。
1.2 协议定义
- SSL (Secure Sockets Layer): 安全套接字层协议。
- TLS (Transport Layer Security): 传输层安全性协议。
- 关系: TLS 是 SSL 的升级版。在讨论中,两者常被视为同一概念。
1.3 HTTPS 的构成
HTTPS 并非一个全新的协议,它的本质是在 HTTP 和 TCP 之间增加了一个安全层。
- 标准 HTTP 通信模型:
应用层: HTTP | 传输层: TCP | 网络层: IP - HTTPS 通信模型:
应用层: HTTP | 安全层: SSL/TLS <-- 新增的安全层 | 传输层: TCP | 网络层: IP
核心结论: 理解了
SSL/TLS的工作原理,就等于理解了HTTPS的核心。
2. 为什么需要安全传输?
2.1 问题的根源:明文传输
- 传输安全: 保护数据在客户端和服务器之间传输的过程中,不被第三方窃取或篡改。
- 网络路径: 客户端与服务器的通信需经过多个网络节点(如路由器)。
- 风险: 任何一个中间节点都可能被攻击者(中间人)控制,从而监听或修改传输的明文数据。
2.2 中间人攻击 (Man-in-the-Middle Attack) 示例
- 场景:
- 客户端 (邓哥) -> 想发送 "我爱你" -> 服务器 (莫妮卡)
- 攻击者 (陈哥) 潜伏在中间节点。
- 攻击过程:
- 邓哥发送明文消息 "我爱你"。
- 陈哥在中间节点截获该消息。
- 陈哥将消息篡改为 "我恨你"。
- 陈哥将篡改后的消息转发给莫妮卡。
- 莫妮卡收到 "我恨你",并认为是邓哥的真实意图,造成严重后果。
HTTP 协议就是这种无保护的明文传输,请求和响应都可能被中间人截获和篡改(例如,在正常网页中注入弹窗广告)。
3. 安全方案的演进
3.1 方案一:对称加密
- 原理: 使用同一个密钥进行加密和解密。
- 优点: 加解密速度快,效率高,适合海量数据通信。
- 流程设想:
- 客户端请求密钥。
- 服务器将对称密钥
key1发送给客户端。 - 客户端使用
key1加密数据后发送。
- 漏洞:
- 在第 2 步中,服务器发送密钥
key1的过程是明文的。 - 中间人陈哥可以直接截获这个密钥
key1。 - 后续客户端使用
key1加密的数据,陈哥因为拥有key1,可以轻松解密、篡改、再加密后发给服务器。 - 结论: 对称加密方案失败,因为密钥分发过程不安全。
- 在第 2 步中,服务器发送密钥
3.2 方案二:非对称加密
- 原理: 一对密钥,公钥 (
PublicKey) 和私钥 (PrivateKey)。- 公钥加密的数据,只有对应的私钥能解密。
- 私钥加密/签名的数据,对应的公钥能解密/验证。
- 流程设想 (问题):
- 服务器将公钥发给客户端。
- 客户端用公钥加密 "我爱你" 并发送。
- 服务器用私钥解密,成功收到消息。
- 问题出现: 服务器回复 "你是个好人",用什么加密?如果用公钥加密,客户端没有私钥,无法解密。
3.3 方案三:非对称加密 + 对称加密 (混合方案)
这是现代 HTTPS 采用的核心思想。
核心思路:
- 使用非对称加密来安全地协商出一个对称加密的密钥。
- 使用协商好的对称加密密钥来加密后续的所有通信内容。
流程设想:
- 服务器将自己的公钥
PublicKey_S发送给客户端。 - 客户端随机生成一个对称加密的密钥
key_symmetric。 - 客户端使用服务器的公钥
PublicKey_S来加密这个对称密钥key_symmetric。 - 客户端将加密后的对称密钥发送给服务器。
- 服务器使用自己的私钥
PrivateKey_S解密,得到对称密钥key_symmetric。 - 至此,双方都拥有了同一个对称密钥
key_symmetric,且该密钥的传输过程是安全的。 - 后续所有通信都使用
key_symmetric进行对称加密。
- 服务器将自己的公钥
新的漏洞 (终极问题):
- 中间人陈哥依然可以在第 1 步动手脚。
- 服务器发送公钥
PublicKey_S时,陈哥截获。 - 陈哥自己生成一对新的公私钥:
PublicKey_C和PrivateKey_C。 - 陈哥将服务器的公钥
PublicKey_S存起来,然后把自己的公钥PublicKey_C发送给客户端。 - 客户端毫不知情,以为收到的是服务器的公钥,于是用
PublicKey_C加密了对称密钥key_symmetric并发送。 - 陈哥截获后,用自己的私钥
PrivateKey_C解密,成功获取了对称密钥key_symmetric。 - 为了让通信继续,陈哥再用之前保存的服务器公钥
PublicKey_S加密key_symmetric,然后发给服务器。 - 最终,客户端、服务器都能正常通信,但他们协商出的对称密钥已被陈哥掌握,所有通信内容对他而言都是透明的。
根本原因: 客户端无法验证收到的公钥到底是不是目标服务器的。这就是信任问题。
4. 终极解决方案:CA 与数字证书
为了解决信任问题,必须引入一个权威的、所有人都信任的第三方机构。
- CA (Certificate Authority): 证书颁发机构。一个全球公认的可信实体。
4.1 数字证书 (Digital Certificate)
服务器不再直接发送公钥,而是向 CA 机构申请一个数字证书,然后将证书发给客户端。
- 申请流程: 服务器生成一对公私钥,然后将公钥和自己的域名、身份信息等提交给 CA。
- 证书内容:
- 颁发机构 (Issuer): 是哪个 CA 机构颁发的。
- 网站域名 (Subject): 该证书是颁发给哪个网站的。
- 服务器公钥 (Public Key): 服务器的公钥。
- 有效期 (Validity): 证书的有效时间。
- 数字签名 (Digital Signature): 证书的防伪关键。
4.2 数字签名 (Digital Signature)
生成过程:
- CA 使用一种哈希算法,计算出证书主要内容(域名、服务器公钥等)的信息摘要。
- CA 使用自己的私钥对这个信息摘要进行加密。
- 这个加密后的摘要就是数字签名。
验证过程 (由浏览器/客户端自动完成):
- 浏览器获取到服务器发来的证书。
- 浏览器使用同样的哈希算法,计算出证书主要内容的信息摘要 A。
- 浏览器使用内置在操作系统或浏览器中的 CA 公钥,对证书里的数字签名进行解密,得到信息摘要 B。
- 对比
A和B是否相等。- 如果相等: 证明:
- 证书内容没有被篡改过(否则摘要 A 会不同)。
- 这个证书确实是由该 CA 颁发的(否则无法用 CA 公钥解密签名)。
- 如果不相等: 证明证书是伪造的或被篡改了,连接不安全。
- 如果相等: 证明:
4.3 最终的安全握手流程 (TLS Handshake)
- Client Hello: 客户端向服务器发起请求,并告知自己支持的 TLS 版本、加密算法套件、一个随机数
random_C等信息。 - Server Hello: 服务器选择一套加密算法,返回自己的数字证书和一个随机数
random_S。 - Client Verification & Key Exchange: a. 验证证书: 客户端验证证书的合法性(见面试题部分)。 b. 获取公钥: 验证通过后,从证书中取出服务器的公钥
PublicKey_S。 c. 生成预主密钥: 客户端生成第三个随机数pre_master_secret。 d. 加密并发送: 使用服务器的公钥PublicKey_S加密pre_master_secret后发送给服务器。 - Server Decryption: 服务器使用自己的私钥
PrivateKey_S解密,得到pre_master_secret。 - 生成会话密钥: 客户端和服务器同时使用
random_C、random_S和pre_master_secret这三个随机数,通过约定的算法各自独立计算出最终的会话密钥 (Session Key)。 - Handshake Finished: 双方互相发送一个 "握手结束" 的消息,该消息会用刚刚生成的会话密钥加密。如果对方能成功解密,说明握手成功。
- Secure Communication: 后续所有应用层数据(HTTP 请求/响应)都使用这个会话密钥进行对称加密传输。
此时,中间人陈哥因为没有服务器的私钥,无法解密
pre_master_secret,因此无法计算出会话密钥,只能看到一堆无法破解的加密数据。
5. 面试核心问题
Q1: 什么是中间人攻击?有了 HTTPS 后还能攻击吗?
回答: 中间人攻击 (MITM) 指的是攻击者在通信双方之间插入自己,窃听或篡改信息。HTTPS 的设计目标就是为了防御此类攻击。但理论上,在特定条件下,仍可能存在攻击方式:
- SSL 劫持攻击 (SSL Hijacking): 攻击者伪造一个服务器的证书(自签名证书)发给客户端。此时客户端的浏览器会弹出严重的安全警告(“您的连接不是私密连接”),提示证书的颁发机构不受信任。如果用户忽略警告并选择继续访问,那么攻击就可能成功。
- SSL 剥离攻击 (SSL Stripping): 用户请求
https://example.com,攻击者截获请求后,自己与https://example.com建立安全的 HTTPS 连接,但与用户之间建立的是不安全的 HTTP 连接。它将所有 HTTPS 链接替换为 HTTP 链接返回给用户。用户看到的是 HTTP 网站,地址栏没有锁,但可能不会注意到。为了防范此攻击,现代浏览器对 HTTP 网站会明确标记 "不安全"。
Q2: 简述一下 HTTPS (TLS) 的握手过程。
回答: HTTPS 握手过程主要目的是安全地协商出一个用于后续通信的对称密钥。
- 客户端问候 (Client Hello): 客户端发送支持的 TLS 版本、加密套件和客户端随机数。
- 服务器响应 (Server Hello): 服务器确定加密套件,发送其数字证书和服务器随机数。
- 客户端验证与密钥交换:
- 客户端验证服务器证书的合法性。
- 验证通过后,生成一个"预主密钥"(Pre-master secret)。
- 使用证书中的服务器公钥加密这个"预主密钥"并发送给服务器。
- 服务器解密与密钥生成:
- 服务器用自己的私钥解密,得到"预主密钥"。
- 双方根据三个随机数(客户端随机数、服务器随机数、预主密钥)独立计算出相同的会话密钥。
- 握手完成: 双方交换使用会话密钥加密的"握手完成"消息,验证密钥协商成功。之后所有通信都使用该会话密钥进行对称加密。
Q3: 客户端如何验证证书的合法性?
回答: 客户端(浏览器)会执行以下一系列检查:
- 信任链验证: 检查证书的颁发机构 (CA) 是否是操作系统或浏览器信任的根 CA。它会沿着证书链一直向上追溯,直到找到一个可信的根证书。
- 有效期验证: 检查当前系统时间是否在证书的有效期之内。
- 吊销状态验证: 通过在线证书状态协议 (OCSP) 或证书吊销列表 (CRL) 查询该证书是否已被颁发机构吊销。
- 域名验证: 检查证书上记录的域名是否与当前正在访问的网站域名一致。
- 签名验证: 使用 CA 的公钥解密证书的数字签名,并与自己计算的证书信息摘要进行对比,确保证书未被篡改。
Q4: 为什么需要 CA 机构对证书进行签名?
回答: 核心是为了解决信任问题。如果没有权威的 CA 签名:
- 任何人都可以自己生成证书,这使得客户端无法分辨一个证书的真伪。
- 中间人可以轻易地用自己的假证书替换掉服务器的真证书,客户端无法察觉,导致 HTTPS 失去意义。 CA 作为一个受信任的第三方,它的签名就相当于一个权威的担保,向客户端保证:“这个证书里的公钥确实属于这个域名,你们可以放心使用它进行加密通信。”