面试知识库
极高 进阶

HTTPS与TLS握手#

一句话答案#

HTTPS = HTTP + TLS 加密,握手:Client Hello→Server Hello+证书→密钥交换→对称加密通信。

核心要点

TLS 1.2 握手(4次往返,2-RTT):

TLS 1.3 优化(1-RTT,甚至 0-RTT):

  • 精简了握手,去掉了 ServerHelloDone、ChangeCipherSpec 等消息
  • 只支持前向安全的密钥交换算法(ECDHE),不再支持 RSA 静态密钥交换
  • 0-RTT 恢复会话(Session Resumption)

客户端如何验证 CA 证书的有效性:

证书链验证:

服务端证书(由中间 CA 签名)
  → 中间 CA 证书(由根 CA 签名)
  → 根 CA 证书(由操作系统/浏览器内置信任)

验证流程:
  1. 用中间 CA 的公钥验证服务端证书的签名 → 合法(确认证书是中间 CA 颁发的)
  2. 用根 CA 的公钥验证中间 CA 证书的签名 → 合法
  3. 根 CA 证书在操作系统受信任根证书列表中 → 整个链可信
plaintext

其他验证项:

  • 域名匹配:证书中的 CN(Common Name)或 SAN 是否与访问的域名一致
  • 有效期:证书是否在有效期内(notBefore ~ notAfter)
  • 吊销状态
    • CRL(Certificate Revocation List):下载吊销列表检查
    • OCSP(Online Certificate Status Protocol):在线实时查询证书状态

三个深挖点:签名、Finished、前向安全#

1. 数字签名的本质 = 哈希 + 私钥加密

证书”由 CA 签名”到底签了什么、怎么验?

CA 签发时:
  对证书内容(域名、公钥、有效期…)做哈希 → 得到摘要 digest
  用 CA 的【私钥】加密 digest → 这就是"数字签名",附在证书里

客户端验证时:
  ① 同样对证书内容做一遍哈希 → 得到 digest1
  ② 用 CA 的【公钥】解密签名 → 得到 digest2
  ③ 比对 digest1 == digest2 ?
       相等 → 证书内容没被篡改,且确实是这个 CA 用私钥签的
       不等 → 证书被改过 / 不是该 CA 签的,验证失败
plaintext
  • 为什么能防伪造:只有 CA 持有私钥,别人无法伪造出能被 CA 公钥正确解开的签名
  • 为什么能防篡改:改了证书任何一个字节(比如把域名换成自己的),哈希就变了,digest1 ≠ digest2,立刻露馅。
  • 这同时验证了两件事:证书未被篡改 + 该公钥确实属于这个域名(因为域名和公钥都在被签名的内容里)。

注意方向:日常加密是”公钥加密、私钥解密”;签名正好相反——私钥加密(签)、公钥解密(验),因为目的不是保密而是证明”这是私钥持有者干的”。

2. Finished 报文:握手的防篡改/防降级校验

握手前半段(ClientHello、加密套件协商等)大多是明文传输的,中间人可以悄悄篡改,比如把”支持 TLS 1.3”改成”只支持弱加密套件”来发起降级攻击。Finished 就是用来兜底的:

  • Finished 报文里携带一个对前面所有握手消息计算出的 MAC(基于已协商出的密钥)。
  • 双方各自把自己看到的握手消息序列算一遍 MAC,互相核对。
  • 如果中间人改过任何一条握手消息,两边算出的 MAC 对不上,握手直接失败中断
  • 因为 MAC 依赖刚协商出的会话密钥,中间人没有密钥就伪造不出正确的 Finished,于是篡改和降级都会被发现。

3. ECDHE 与前向安全(Forward Secrecy)

这是 TLS 1.3 弃用 RSA 静态密钥交换、只保留 ECDHE 的根本原因。

密钥交换方式做法风险
RSA 静态客户端用服务器证书里的长期公钥加密 pre-master secret 发过去一旦服务器长期私钥泄露,攻击者可解开历史上抓包存下的所有流量
ECDHE 临时每次握手双方临时生成一对椭圆曲线密钥做 DH 交换,算出本次会话密钥,握手后临时私钥即丢弃长期私钥只用于”签名证明身份”,不参与加密会话密钥

前向安全:每次会话用的是一次性临时密钥,即使服务器长期私钥日后泄露,也无法倒推出历史会话密钥、解密过去的流量。RSA 静态交换不具备这个性质——长期私钥就是历史流量的总钥匙,所以 TLS 1.3 直接废弃了它。

面试回答(2分钟版)

HTTPS本质是HTTP加上TLS加密层。以TLS 1.2为例,握手过程是这样的:客户端先发ClientHello,携带支持的TLS版本、加密套件列表和一个客户端随机数;服务端回复ServerHello选定加密套件,附带服务端随机数和数字证书。客户端收到证书后进行验证,包括证书链校验、域名匹配、有效期和吊销状态检查。验证通过后客户端生成pre-master secret,用服务端公钥加密发送过去。双方各自根据客户端随机数、服务端随机数和pre-master secret计算出相同的Master Secret,派生出对称加密密钥,之后所有数据传输都用对称加密。这里的核心设计是非对称加密只用于密钥交换阶段,数据传输用对称加密保证性能。TLS 1.3做了重大优化,握手从2个RTT降到1个RTT,只保留前向安全的ECDHE算法,还支持0-RTT会话恢复。需要注意的是HTTPS并非绝对安全,如果客户端不校验证书仍然可能遭受中间人攻击。

追问与易错

追问方向:

  • “对称加密和非对称加密各用在哪?”→ 非对称加密(RSA/ECDHE)用于 TLS 握手阶段交换密钥,对称加密(AES)用于后续数据传输,兼顾安全和性能
  • “数字证书怎么验证真伪?”→ 用 CA 公钥验证证书签名 + 证书链逐级校验到根 CA + 检查域名匹配、有效期和吊销状态(CRL/OCSP)
  • “HTTPS 比 HTTP 慢多少?怎么优化?”→ TLS 1.2 握手增加 2-RTT,优化方案:升级 TLS 1.3(1-RTT)、Session 复用(0-RTT)、OCSP Stapling 减少证书验证延迟
  • “数字签名到底是怎么做的?”→ 哈希 + 私钥加密:CA 对证书内容哈希后用 CA 私钥加密成签名;客户端用 CA 公钥解密签名得到摘要,再自己对证书算一遍哈希比对,相等说明证书未被篡改且确属该域名。方向和加密相反(私钥签、公钥验)
  • “Finished 报文有什么用?”→ 对前面所有握手消息做 MAC 校验,两端互相核对;中间人篡改任何握手消息或发起降级攻击都会导致 MAC 对不上、握手中断,且中间人无会话密钥伪造不出正确 Finished
  • “什么是前向安全?为什么 TLS 1.3 弃用 RSA 密钥交换?”→ ECDHE 每次握手用一次性临时密钥对,长期私钥只用于签名不参与加密会话密钥;即使长期私钥日后泄露也无法解密历史流量。RSA 静态交换中长期私钥是历史流量的总钥匙、不具备前向安全,故被废弃

易错点:

  • ❌ “HTTPS 全程非对称加密”——只有密钥交换用非对称,数据传输用对称(性能考虑)
  • ❌ “有了 HTTPS 就绝对安全”——中间人攻击仍可能(如客户端不验证证书)
  • ❌ “签名就是把证书用私钥加密”——签的是证书内容的哈希摘要,不是整张证书;且签名方向是私钥签、公钥验,与加密保密相反