加密和签名

加密和签名

加密:公钥加密,私钥解密。
签名:私钥签名,公钥验签。
特性 加密 签名
目的 保密 验证身份、完整性
结果 密文 数字签名
解密者 接收者 接收者验证签名
密钥方向 公钥加密,私钥解密(非对称) 私钥签名,公钥验签

签发证书

根 CA 证书的私钥一般离线保存,不会直接签发服务器证书。根 CA 只签发中间 CA → 中间 CA 再签发服务器证书。签发服务器证书过程如下:

  1. 网站生成自己的公私钥对
  2. 网站通过公钥、域名、公司等信息创建一个 CSR(Certificate Signing Request),将 CSR 发给一个 CA(证书颁发机构,如 Let's Encrypt, DigiCert)。
  3. CA 验证身份(比如通过 DNS 验证网站域名归属),CA 用它的中间证书的私钥对 CSR 签名,生成服务器证书(.crt 或 .pem 文件),CA 会把服务器证书和中间证书一同返回给网站。

网站收到 CA 签发的证书之后,会在服务器进行配置。服务器配置时,将服务器证书和中间证书合并为一个文件(PEM 多段),这个拼接的文件被称为证书链文件,服务器在 TLS 握手时发送整个链,让客户端一步步向上验证到可信的 Root CA.

ssl_certificate     /etc/ssl/fullchain.pem;  # 包含 leaf + 中间证书
ssl_certificate_key /etc/ssl/private.key;    # 私钥

验证证书

CA 机构颁发证书流程(以 Let’s Encrypt 为例):

ECDSA 用户证书 ← ECDSA 中间证书(E5 或 E6)← ISRG Root X1

客户端收到证书链 [Leaf, Intermediate, (Root optional)] 之后,验证过程如下:

  1. 验证 Leaf 证书的签名 —— 用 Intermediate 证书的公钥
  2. 验证 Intermediate 证书的签名 —— 用 Root 证书的公钥
  3. 检查 Root 是否存在于客户端的受信任根证书列表
  4. 所有签名验证成功 ⇒ 认证通过

证书链结构在逻辑上是从 Root → Intermediate → Leaf 建立的。CA 们按这个方向颁发证书(签名)。

证书链的验证是从服务器证书(最下级)开始,一步步“往上”验证签名,一直验证到根证书为止。

阶段 行为 顺序
CA 机构签发证书 根 CA → 中间 CA → 服务器证书 从上往下
浏览器验证证书链 服务器证书 → 中间证书 → 根 CA 从下往上

HTTPS 建立连接过程

以 TLS 1.3 协议为例,TLS 握手阶段主要完成以下四件大事:

阶段 目的
1. 握手(握手阶段) 协商协议版本、密码算法,生成随机数等
2. 身份认证 验证服务器证书合法性,防中间人攻击
3. 密钥协商 安全地建立对称密钥,用于加密传输
4. 加密通信 使用协商好的对称密钥进行加密传输

📘 使用 TLS 1.3 的全过程(现代浏览器默认使用)

我们以 TLS 1.3 为例(相比 TLS 1.2 简化了很多),详细讲解全过程。

🔐 第 0 步:客户端准备

客户端(浏览器)准备:

  • 支持的 TLS 版本(例如 TLS 1.3)
  • 支持的密码套件(如 TLS_AES_128_GCM_SHA256
  • 支持的密钥交换算法(如 X25519
  • 生成一个随机数(client_random
  • 生成一个 ECDHE 公钥(用于密钥交换)

🧾 第 1 步:ClientHello(客户端发起)

客户端向服务器发送 ClientHello,包括:

ClientHello {
  version: TLS 1.3,
  random: client_random,
  cipher_suites: [TLS_AES_128_GCM_SHA256, ...],
  key_share: [ECDHE 公钥],
  supported_groups: [X25519, secp256r1, ...]
}

🔐 第 2 步:ServerHello(服务器回应)

服务器收到 ClientHello 后:

  1. 选定双方支持的密码算法(如 TLS_AES_128_GCM_SHA256)
  2. 生成自己的随机数(server_random
  3. 生成自己的 ECDHE 公钥
  4. 选一个自己的证书(通常是服务器证书,含 RSA/ECDSA 公钥)
  5. 用证书对应私钥签名整个握手内容,证明身份

返回如下:

ServerHello {
  random: server_random,
  key_share: [ECDHE 公钥],
  certificate: 服务器证书链(leaf + intermediate)
  CertificateVerify: 用服务器私钥签名握手数据
  Finished: 对全部握手数据生成 MAC 校验
}

🛂 第 3 步:客户端验证服务器身份

客户端收到服务器证书链后:

  1. 验证证书链

    • 使用本地的根 CA 公钥,逐级验证中间证书 → Leaf 证书
  2. 验证签名

    • 使用 Leaf 证书的公钥验证 CertificateVerify 签名(确认服务器确实拥有私钥)

验证通过 ⇒ 确认服务器身份可信

🔑 第 4 步:共享密钥计算(ECDHE)

客户端与服务器分别用自己的私钥 + 对方的公钥进行 ECDH 运算,这一步输出的 shared_secret 是相同的。:

shared_secret = ECDH(client_private, server_public)

然后使用 HKDF(HMAC-based KDF)进行密钥派生:

handshake_secret = HKDF(shared_secret, client_random, server_random)
application_secret = HKDF(handshake_secret, “finished”, …)

得出:

  • 对称加密密钥(如 AES-128-GCM)
  • 消息完整性验证密钥(HMAC)

✅ 第 5 步:客户端发送 Finished

客户端也发送一个 Finished 消息,表明:

  • 握手过程没被篡改
  • 客户端也完成密钥协商

此后双方正式进入应用层加密通信。

🔐 第 6 步:加密传输阶段(HTTP 加密)

此时 HTTP 请求和响应全部使用协商好的对称加密算法进行加密。

加密内容包括:

  • HTTP 请求/响应头与正文
  • Cookie、表单数据
  • TLS 自身的验证消息等

如:

  • 浏览器发出 GET /index.html,数据先被 AES 加密
  • 服务端返回 HTML 内容,也使用对称密钥加密

整个通信过程为:

[客户端] ⇄ (TLS加密层) ⇄ [服务器]
      ↑                        ↑
    HTTP                  HTTP

📌 补充:TLS 1.3 安全特性

特性 含义
Forward Secrecy 前向保密性,历史通信无法因密钥泄漏而解密
少量 RTT(0-RTT) 可缓存会话密钥,提升性能
更强加密 默认仅支持 AEAD(如 AES-GCM,ChaCha20)
简化握手 无 ServerKeyExchange、无 ChangeCipherSpec

🧠 总结流程图(TLS 1.3)

ClientHello (ECDHE 公钥 + 支持的套件)
        ↓
ServerHello (ECDHE 公钥 + 服务器证书链 + 签名)
        ↓
双方计算 shared_secret(ECDHE)
        ↓
验证服务器身份(证书 + 签名)
        ↓
双方生成对称密钥(HKDF 派生)
        ↓
客户端发送 Finished(握手完成)
        ↓
双向使用对称加密通信(HTTP over TLS)

🔧 实际抓包工具

你可以用以下工具实际查看 TLS 握手细节:

  • Wireshark(过滤条件:tcp.port == 443tls
  • openssl s_client -connect example.com:443 -tls1_3 -showcerts
  • curl -v --http2 https://example.com

✅ 总结

阶段 目的 安全机制
ClientHello 发起连接,请求协商 客户端随机数、支持的算法
ServerHello 响应连接,返回证书 服务器证书、公钥签名、ECDHE 公钥
验证证书 防中间人攻击 签名 + 证书链验证
密钥协商 建立对称密钥 ECDHE + HKDF
Finished 确认握手成功 HMAC 校验所有握手数据
加密通信 传输数据 AES-GCM / ChaCha20
posted @ 2025-01-06 13:46  nptr  阅读(71)  评论(0)    收藏  举报