HTTPS加解密流程解析

发布于:2025-09-10 ⋅ 阅读:(12) ⋅ 点赞:(0)

HTTPS(HTTP over TLS/SSL)的数据加密交互流程,核心是通过 TLS(Transport Layer Security)握手协议 来建立一个安全、加密的通信通道。整个过程结合了非对称加密对称加密,确保数据的机密性、完整性、身份认证


🔐 HTTPS 加密交互流程(以 TLS 1.2/1.3 为例)

我们以用户访问 https://www.example.com 为例,详细说明加密交互流程。


🌐 第一阶段:TCP 连接建立(前置步骤)

Client (浏览器)          Server (Web 服务器)
       |------------------------>|
       |     TCP 三次握手       |
       |<------------------------|
  • 浏览器先通过 DNS 解析 IP 地址
  • 然后与服务器建立 TCP 连接(端口 443)

🔐 第二阶段:TLS 握手(加密通道建立)

✅ 步骤 1:Client Hello(客户端发起)
Client → Server:
  - 支持的 TLS 版本(如 TLS 1.2, 1.3)
  - 支持的加密套件(Cipher Suites)
    例如:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  - 客户端随机数(Client Random)
  - 支持的压缩方法
  - SNI(Server Name Indication): "www.example.com"

📌 作用:告诉服务器“我能用什么加密方式”。


✅ 步骤 2:Server Hello(服务器响应)
Server → Client:
  - 选定的 TLS 版本
  - 选定的加密套件
  - 服务器随机数(Server Random)
  - (可选)会话 ID(用于会话恢复)

📌 作用:协商出双方都支持的加密参数。


✅ 步骤 3:Server Certificate(服务器发送证书)
Server → Client:
  - 数字证书(X.509 格式)
    包含:
      • 服务器域名(Common Name / SAN)
      • 公钥(Public Key)
      • 颁发机构(CA,如 Let's Encrypt)
      • 有效期
      • 数字签名

🔍 浏览器会验证:

  • 证书是否由可信 CA 签发
  • 域名是否匹配(防钓鱼)
  • 是否在有效期内
  • 是否被吊销(CRL/OCSP)

✅ 步骤 4:Server Key Exchange(可选,取决于加密套件)
Server → Client:
  - 临时公钥(如 ECDHE 的椭圆曲线参数)
  - 签名(用私钥对握手消息签名,证明身份)

⚠️ 仅在使用 ECDHEDHE 等前向安全密钥交换时需要。


✅ 步骤 5:Server Hello Done
Server → Client:
  - "我发完了"

✅ 步骤 6:Client Key Exchange(客户端生成会话密钥)
Client → Server:
  - 生成一个 **预主密钥(Pre-Master Secret)**
  - 用服务器证书中的**公钥加密**它
  - 发送给服务器

🔐 例如:

  • 如果使用 RSA:客户端生成随机数,用服务器公钥加密发送
  • 如果使用 ECDHE:客户端生成自己的临时密钥对,发送公钥部分

✅ 步骤 7:客户端验证(可选)
Client → Server:
  - 客户端用私钥签名一段握手消息(双向认证时)

🔐 双向认证(mTLS)才需要,普通 HTTPS 不需要。


✅ 步骤 8:生成主密钥(Master Secret)

客户端和服务器各自计算:

Master Secret = PRF(Pre-Master Secret, "master secret",
                    Client Random + Server Random)

然后从 Master Secret 派生出:

  • 会话密钥(Session Keys)
    • 对称加密密钥(如 AES-128)
    • MAC 密钥(消息认证码)
    • 初始向量(IV)

🔑 所有后续通信都使用对称加密,速度快。


✅ 步骤 9:Change Cipher Spec(切换加密模式)
Client → Server:
  - "我准备用加密通信了"
Server → Client:
  - "我也准备好了"

🔄 双方通知对方:从现在开始,所有消息都要加密。


✅ 步骤 10:Finished(握手完成)
Client → Server:
  - 发送一条用会话密钥加密的“Finished”消息
    (包含之前所有握手消息的哈希值)
Server → Client:
  - 回复一条加密的“Finished”消息

✅ 双方验证:

  • 解密是否成功
  • 哈希值是否匹配
  • 证明密钥一致、握手未被篡改

📢 第三阶段:加密数据传输(应用层通信)

Client ⇄ Server
  - 使用协商好的对称加密算法(如 AES-GCM)
  - 加密 HTTP 请求和响应
  - 每条消息带 MAC(防篡改)

例如:

GET /index.html HTTP/1.1
Host: www.example.com

→ 被 AES 加密成乱码传输


🔄 TLS 1.3 的优化(更快更安全)

TLS 1.3 简化了握手过程,支持 1-RTT 甚至 0-RTT

Client Hello(带密钥共享)
      ↓
Server Hello(带密钥共享 + 证书 + Finished)
      ↓
Client(发送 Finished + HTTP 请求)
  • 减少往返次数
  • 默认启用前向安全(PFS)
  • 移除不安全加密套件

在 TLS 1.3 中,Client Hello 消息中包含了“密钥共享”(Key Share)信息,即客户端生成的一个临时公钥(ephemeral public key),用于密钥交换。你可能会担心:

❓“Client Hello 是明文传输的,攻击者不是可以直接看到这个‘密钥’吗?那不就泄露了?”

我们来详细解释:为什么即使 Client Hello 是明文的,也能保证密码传输的安全性


🔐 核心答案:使用 ECDHE(椭圆曲线迪菲-赫尔曼临时密钥交换) 实现 前向保密(PFS)

关键点:Client Hello 中发送的不是“密码”,而是用于 密钥协商的临时公钥,它本身无法直接解密通信内容。真正的“共享密钥”是在双方本地通过数学运算生成的,永远不会在网络上传输


🧩 详细流程解析

我们以 ECDHE + RSA 签名 为例(常见组合):

1. Client Hello(明文,但安全)

Client → Server:
  - 支持的 TLS 版本(TLS 1.3)
  - 支持的加密套件
  - 客户端随机数(Client Random)
  - Key Share(关键!):
      • 椭圆曲线类型(如 x25519)
      • 客户端的临时公钥(Client Ephemeral Public Key)

📌 这个“临时公钥”是一次性的,本次会话结束后就丢弃。


2. Server Hello(响应)

Server → Client:
  - 选定的加密套件
  - 服务器随机数(Server Random)
  - Server Key Share:
      • 服务器的临时公钥(Server Ephemeral Public Key)
  - 服务器证书(包含长期 RSA/ECC 公钥)
  - 证书签名(用服务器私钥签名握手消息)
  - Finished(加密)

3. 双方计算共享密钥(关键!)

🔐 数学原理:迪菲-赫尔曼密钥交换(Diffie-Hellman)
  • 客户端有:

    • 自己的临时私钥(client_priv
    • 服务器的临时公钥(server_pub
  • 服务器有:

    • 自己的临时私钥(server_priv
    • 客户端的临时公钥(client_pub
双方各自计算:
共享密钥 = ECDH(自己的私钥, 对方的公钥)
  • 客户端计算:ECDH(client_priv, server_pub)
  • 服务器计算:ECDH(server_priv, client_pub)

✅ 数学保证:两者结果完全相同

但这个共享密钥从未在网络上传输


🔍 为什么攻击者无法破解?

即使攻击者监听到:

  • Client Hello 中的 client_pub
  • Server Hello 中的 server_pub

仍然无法计算出共享密钥,因为:

❌ 他没有:

  • 客户端的临时私钥(client_priv
  • 服务器的临时私钥(server_priv

而从公钥推导私钥,在椭圆曲线密码学(ECC)中是计算不可行的(离散对数问题)。


✅ 安全特性保障

特性 如何实现
前向保密(PFS) 每次会话使用不同的临时密钥对,即使长期私钥泄露,也无法解密过去会话
身份认证 服务器用长期私钥对握手消息签名,客户端用证书验证
机密性 共享密钥用于生成对称加密密钥(AES-GCM)
完整性 使用 AEAD 模式(如 GCM)防篡改

🔄 与 TLS 1.2 的对比(为什么 TLS 1.3 更安全)

特性 TLS 1.2 TLS 1.3
密钥交换 RSA 或 ECDHE 仅支持 ECDHE(强制前向保密)
握手延迟 2-RTT 1-RTT 或 0-RTT
密钥共享 在 Client Key Exchange 中发送 在 Client Hello 中发送
安全性 依赖 RSA 加密预主密钥 依赖 ECDHE 协商,更抗量子攻击

⚠️ TLS 1.2 中如果使用 RSA 密钥交换,攻击者若事后获取服务器私钥,可解密所有历史通信(无前向保密)。


🎯 总结:为什么 Client Hello 带密钥共享是安全的?

问题 解答
Client Hello 是明文的? 是的,但只包含临时公钥,不是密钥本身
共享密钥在哪生成? 在客户端和服务器本地计算不传输
攻击者能看到公钥? 能,但无法从公钥推导私钥(ECC 难题)
是否前向保密? ✅ 是,每次会话密钥独立
如何防止中间人? 服务器用私钥签名握手消息,客户端验证证书

🔐 一句话总结
TLS 1.3 的“密钥共享”不是传输密码,而是通过 ECDHE 协议,让双方在不安全的信道上共同协商出一个只有他们知道的共享密钥,即使攻击者看到所有消息,也无法计算出这个密钥 —— 这就是现代密码学的魔法。✨

🔐 加密技术总结

技术 用途
非对称加密(RSA/ECC) 安全传输“预主密钥”,身份认证
对称加密(AES/ChaCha20) 高效加密实际数据
数字证书(X.509) 验证服务器身份
哈希函数(SHA-256) 数据完整性校验
HMAC / AEAD 防篡改(完整性)
ECDHE 实现前向保密(PFS)

✅ 安全特性保障

目标 实现方式
机密性 对称加密(AES)
完整性 HMAC / GCM 模式
身份认证 数字证书 + CA 信任链
防重放攻击 随机数 + 序列号
前向保密(PFS) ECDHE 密钥交换

🎯 总结:HTTPS 加密流程一句话

浏览器和服务器先用非对称加密协商出一个共享密钥,然后用这个密钥进行对称加密通信,全程通过数字证书验证身份,确保你访问的是真正的网站。



在 TLS 1.3 中,服务器证书的核心用途是:实现服务器身份认证(Authentication),防止中间人攻击(Man-in-the-Middle Attack)。

虽然 TLS 1.3 的密钥交换(如 ECDHE)已经通过数学方式安全地协商出了加密密钥,但密钥交换本身无法验证对方身份。这就是服务器证书的关键作用。


🔐 一、服务器证书的核心用途

用途 说明
身份认证 证明“你正在通信的服务器确实是 www.example.com,而不是黑客伪造的”
公钥分发 安全地将服务器的公钥传递给客户端(用于签名验证)
信任链建立 通过 CA(证书颁发机构)的数字签名,建立可信身份

🧩 二、TLS 1.3 中服务器证书如何工作?(详细流程)

我们以访问 https://www.example.com 为例:

1. 服务器发送证书

Server → Client:
  - 数字证书(X.509 格式)
    • 域名:www.example.com
    • 服务器的公钥(用于签名验证)
    • 颁发机构(CA):如 Let's Encrypt
    • 有效期
    • CA 的数字签名

🔐 注意:这个公钥不是用于加密数据(TLS 1.3 不再用它加密预主密钥),而是用于验证签名


2. 服务器发送“证书验证”消息(CertificateVerify)

Server → Client:
  - CertificateVerify:
      • 使用服务器的**私钥**,对之前所有握手消息(包括 Client Hello、Server Hello、Key Share 等)进行数字签名

🔍 这是关键一步!它证明:

  • 服务器确实拥有与证书中公钥对应的私钥
  • 握手过程未被篡改

3. 客户端验证证书和签名

客户端执行以下验证:

✅ 步骤 1:验证证书链
  • 检查证书是否由可信 CA 签发(如根证书在操作系统/浏览器信任库中)
  • 验证 CA 的签名是否有效
  • 检查证书是否在有效期内
  • 检查域名是否匹配(防止钓鱼)
  • (可选)检查证书是否被吊销(CRL / OCSP)
✅ 步骤 2:验证签名
  • 使用证书中的公钥解密 CertificateVerify 消息中的签名
  • 对比本地计算的握手消息哈希值
  • 如果一致 → 证明服务器拥有私钥,身份真实

✅ 只有真正的服务器才能用私钥生成正确的签名,中间人无法伪造。


🆚 三、如果没有服务器证书会怎样?

假设没有证书认证:

Client          Attacker          Server
   |    TCP连接    |    TCP连接    |
   |-------------->|-------------->|
   |               |<--------------|  Attacker冒充Server
   |<--------------|               |
   |  ECDHE交换    |  ECDHE交换    |
   |<------------->|<------------->|
   | 加密通信!     |               |
  • 客户端和攻击者也能成功完成 ECDHE 密钥交换
  • 双方也能建立加密通道
  • 但客户端以为自己在和真实服务器通信,实际上所有数据都被攻击者解密、窃听、篡改

🔴 这就是 中间人攻击(MITM)


🎯 四、服务器证书在 TLS 1.3 中的“新角色”

在 TLS 1.2 中,服务器证书的公钥曾用于加密预主密钥(RSA 密钥交换),但在 TLS 1.3 中:

功能 TLS 1.2 TLS 1.3
加密数据 ✅(RSA 密钥交换) ❌(已废弃)
身份认证 ✅(唯一核心用途
签名验证 ⚠️ 部分场景 ✅(强制 CertificateVerify

✅ TLS 1.3 只支持前向安全的密钥交换(如 ECDHE),不再允许用证书公钥直接加密密钥。


✅ 五、总结:服务器证书的用途

问题 回答
服务器证书用于加密数据吗? ❌ 否,TLS 1.3 中不用于加密
那它有什么用? 身份认证 + ✅ 签名验证
如何防止中间人? 服务器用私钥签名握手消息,客户端用证书公钥验证
证书包含的公钥用来做什么? 用于验证 CertificateVerify 签名
为什么不能去掉证书? 否则无法确认对方身份,加密通道无意义

🔐 一句话总结
TLS 1.3 中的服务器证书不用于加密,而是用于“你是谁”的身份证明
它确保你是在和真正的 example.com 通信,而不是一个伪装成它的黑客。
没有它,HTTPS 的“S”(安全)就名存实亡。


网站公告

今日签到

点亮在社区的每一天
去签到