TLS 协议
TLS(Transport Layer Security,传输层安全):一种用于在网络中加密数据传输的协议,旨在保护数据的机密性、完整性和身份验证。
TLS 是 SSL(Secure Sockets Layer,安全套接层)的继任者,提供了更强的安全性和性能。TLS 是 HTTPS、SMTPS、FTPS 等安全协议的基础。
目前常说的ssl实际上一般指tls,ssl因安全问题已被淘汰
TLS 协议旨在在不可信网络(如互联网)上提供**:**
- 机密性(Confidentiality) → 使用对称加密(如 AES)保护传输数据不被窃听。
- 完整性(Integrity) → 使用 MAC(消息认证码)或 AEAD(如 AES-GCM)防止数据被篡改。
- 身份认证(Authentication) → 通常通过 X.509 数字证书 + 公钥基础设施(PKI)验证服务器身份(有时也验证客户端)。
- 前向保密(Forward Secrecy)(TLS 1.2+ 推荐,TLS 1.3 强制) → 即使长期私钥泄露,过去的会话也无法被解密(依赖 ECDHE 等临时密钥交换)。
目前tls主流使用版本tls1.2,优先推荐使用tls1.3)
TLS 的工作原理
1、TLS协议握手
标准TLS会话握手过程包含如下5个阶段:
- ClientHello:客户端发送支持的加密算法列表。
- ServerHello:服务器选择加密算法并发送服务器证书。
- 证书验证:客户端验证服务器证书的有效性。
- 密钥交换:客户端生成预主密钥,用服务器公钥加密后发送。
- 会话密钥:双方根据预主密钥生成会话密钥,用于加密后续通信。
按照版本不同分别展示如下:
逐字节解析整个连接过程: The Illustrated TLS Connection: Every Byte Explained
TLS 1.2 完整握手(Full Handshake)流程图
Client Server | | |--- ClientHello -------------->| (1) 支持的TLS版本、加密套件、随机数 |<-- ServerHello ---------------| (2) 选定参数、服务器随机数 |<-- Certificate ---------------| (3) 服务器证书 |<-- ServerKeyExchange -------->| (4) 若使用DHE/ECDHE,发送临时公钥 |<-- ServerHelloDone ---------->| (5) 服务器握手消息结束 |--- ClientKeyExchange -------->| (6) 客户端发送预主密钥(或临时公钥) |--- [ChangeCipherSpec] ------->| (7) 切换到加密模式 |--- Finished ----------------->| (8) 验证握手完整性 |<-- [ChangeCipherSpec] --------| (9) 服务器切换加密 |<-- Finished ------------------| (10) 服务器验证完成 | | |<==> Application Data <=======>| (11) 加密通信开始TLS 1.3 完整握手(1-RTT)流程图
Client Server | | |--- ClientHello -------------->| (1) 包含客户端密钥共享(如 ECDH 公钥)、 | | 支持的协议、加密套件、随机数 |<-- ServerHello ---------------| (2) 选定参数 + 服务器密钥共享 |<-- Certificate ---------------| (3) 服务器证书(可选) |<-- CertificateVerify -------->| (4) 证书签名验证(证明私钥持有) |<-- Finished ------------------| (5) 服务器完成握手(使用握手密钥加密) |--- [Finished] --------------->| (6) 客户端完成(同样加密) | | |<==> Application Data <======>| (7) 加密应用数据(使用新派生的密钥)其中TLS1.3主要简化了流程将标准2-RTT减小到1-RTT甚至复用下0-RTT
2、TLS握手原理概述
简要概括客户端在建立 TLS 加密过程中主要的工作如下:
-
协商安全参数客户端通过
ClientHello消息向服务器表明自身支持的 TLS 版本、加密套件(如TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)、压缩方法以及两个关键随机数(Client Random)。这些信息为后续密钥派生和算法选择奠定基础。 -
验证服务器身份客户端收到服务器证书后,会执行以下验证:
- 证书是否由受信任的 CA(证书颁发机构)签发;
- 证书是否在有效期内;
- 证书中的域名是否与当前访问的主机名匹配(如 SNI 中指定的
example.com); - 证书链是否完整且可追溯至根 CA。 若任一验证失败,连接将被中止(浏览器通常会弹出警告)。
-
参与密钥协商根据协商的密钥交换算法(如 RSA、ECDHE),客户端执行相应操作:
- RSA 模式:生成一个 48 字节的预主密钥(Pre-Master Secret)(2位固定+46位随机生成的),用服务器证书中的公钥加密后发送;
- (EC)DHE 模式:生成临时的 (EC)DH 密钥对,将临时公钥发送给服务器,并利用对方的临时公钥与自己的私钥计算出共享秘密(即预主密钥)。
现代 TLS(尤其是 TLS 1.3)强制使用 (EC)DHE,以实现前向保密(Forward Secrecy)。
-
派生会话密钥客户端使用预主密钥、Client Random 和 Server Random,通过 PRF(伪随机函数,如 HMAC-SHA256)依次派生出:
- Master Secret(主密钥)
- 多个会话密钥(包括客户端/服务器的加密密钥、MAC 密钥、IV 等) 这些密钥将用于后续对称加密通信(如 AES-GCM)。
-
完成握手并验证完整性客户端发送
Finished消息,该消息包含对整个握手过程所有消息的哈希值,并使用刚生成的会话密钥进行加密和认证。服务器若能正确解密并验证该消息,则证明双方拥有相同的密钥且握手未被篡改。 -
切换至加密通信 自
ChangeCipherSpec之后,所有应用层数据(如 HTTP 请求)均使用协商好的对称加密算法和会话密钥进行加密封装,确保机密性、完整性与身份可信。
整个过程在 TLS 1.3 中被大幅优化:密钥交换与身份认证合并,握手消息加密,且仅需 1 个 RTT 即可开始传输应用数据,显著提升性能与隐私。 预主密钥在client和server端都会生成且由于相互公私钥交换,各自生成的预主密钥是一致的
在此基础上,主密钥=PRF(预主密钥, str(“main secret”), client_random||server_random),生成一直的主密钥后,通过同样PRF生成对应的诸如client_write_secret,server_write_secret等,用于实际的加密解密,此时采用的已经是对称加密。
预主密钥、主密钥等并不会通过网络传输,切记
note: 双随机数是为了避免中间人重放攻击,client和server独立write密钥是为了区分消息主体
Https协议
HTTPS(HyperText Transfer Protocol Secure)不是新协议,而是 HTTP 协议运行在 TLS(或历史上的 SSL)加密通道之上的安全组合。
简单来说HTTPS=HTTP+TLS/SSL+TCP
其实就是在原本http建立完tcp的步奏之后,加入tls握手过程,协商完毕将http协议数据用对称加密传输
ca信任根是公证机构的,类似公安局公章和私章。生成服务器
flowchart TD
%% 🔐 CA 信任根(复用!不动老配置)
CA1[ca.pem<br/>“公安局公章”]
CA2[ca-key.pem<br/>“公安局私章”]
%% 🆕 新服务器专属(全新生成)
K[server-key.pem<br/>私钥 · 随机生成 🔒]
CSR[server.csr<br/>证书签名请求<br/>(含公钥 + CN=IP)]
CNF[extfile.cnf<br/>SAN 声明<br/>IP:192.168.x.x]
%% ✍️ 签名动作
SIGN[openssl x509 -req<br/>CA 盖章认证]
CERT[server-cert.pem<br/>✅ 正式身份证]
K --> CSR
CSR --> SIGN
CNF --> SIGN
CA1 --> SIGN
CA2 --> SIGN
SIGN --> CERT
classDef reuse fill:#e1f5fe,stroke:#01579b
classDef new fill:#e8f5e8,stroke:#1b5e20
classDef action fill:#fff3e0,stroke:#e65100
class CA1,CA2 reuse
class K,CSR,CNF,CERT new
class SIGN action参照这个流程写出复用ca和ca-key生成server-cert的脚本如下