HTTPS (TLS1.2 RSA 模式) 握手流程
1、HTTPS = HTTP + TLS(SSL),端口443;混合加密:握手用非对称加密做身份认证、交换密钥;业务传输用对称加密加密HTTP报文 。
2、非对称加密慢,不会用来加密业务数据,只用来交换会话密钥;对称加密AES速度快,加密真实请求响应数据。
基础概念
- 对称加密:加密解密同一把密钥(会话密钥session‑key),速度快。
- 非对称加密:公钥、私钥成对;公钥加密,私钥解密;私钥签名,公钥验签;性能慢,适合少量数据。
- 数字证书:CA颁发,包含服务器公钥、域名、有效期、CA签名;用来证明服务器身份,防中间人伪造公钥。
TLS1.2‑RSA握手流程图
客户端 服务端
│ │
│──── TCP三次握手,建立TCP连接 ────────▶│
│ │
│ Client Hello │
│ TLS版本、加密套件、【客户端随机数】 │
│─────────────────────────────────────▶│
│ │
│ Server Hello │
│ 选定套件、【服务端随机数】、CA证书 │
│◀─────────────────────────────────────│
│ │
▼▼客户端本地操作▼▼ │
校验证书(签名、有效期、域名)
提取证书中的【服务器公钥】
随机生成【PMS预主密钥】
使用服务器公钥加密PMS
│ │
│ 加密后的PMS(密文) │
│─────────────────────────────────────▶│
│ │ ▲▲服务端本地操作▲▲
│ │ 使用【服务器私钥】解密,得到原始PMS
│ │
▼▼客户端本地计算▼▼ │
输入:客户端随机数 + 服务端随机数 + PMS
算法运算 → 生成【会话密钥】
▶ 服务端同样三份材料,算出完全一样【会话密钥】
│ │
│ ChangeCipherSpec(切换加密模式) │
│─────────────────────────────────────▶│
│ │
│ ChangeCipherSpec │
│◀─────────────────────────────────────│
│ │
│ Finished(握手校验消息,已加密) │
│─────────────────────────────────────▶│
│ │
│ Finished(握手校验消息,已加密)
│◀─────────────────────────────────────│
✅握手完成
后续HTTP请求/响应:全部使用【会话密钥】对称加密传输
步骤精简版
- TCP三次握手建立通道
- 客户端发Client Hello(客户端随机数)给服务端
- 服务端返回Server Hello(服务端随机数+CA证书)给客户端
- 客户端校验证书,生成PMS,用公钥加密PMS发送给服务端
- 服务端私钥解密得到PMS
- 双方用「客户端随机数+服务端随机数+PMS 」各自算出会话密钥
- ChangeCipherSpec通知切换加密模式,交换Finished校验消息
- 握手结束,业务报文使用会话密钥加密通信
步骤详细版
前置:先完成TCP三次握手,建立TCP通道,再开始TLS握手。
- Client Hello(客户端→服务器,明文)
发送:TLS版本、支持的加密套件列表、客户端随机数Client Random、SNI域名。
Client Random:随机种子,后面生成会话密钥的原材料。
-
Server Hello(服务器→客户端,明文)
服务器选出双方都支持的TLS版本、加密套件;返回服务器随机数Server Random;返回CA数字证书(携带服务器公钥)。
-
客户端校验证书
- 校验证书有效期、签名、证书链可信、访问域名和证书域名匹配。
- 校验失败直接断开连接,浏览器报不安全警告。
- 校验成功,从证书取出服务器公钥。
- 客户端生成预主密钥 Pre‑Master‑Secret(PMS)
客户端随机生成48字节PMS,用服务器公钥加密PMS,发送给服务器。
网络传输的是加密后的PMS,中间人拿到也解不开。
- 服务器解密PMS
服务器使用自己的私钥解密报文,拿到原始PMS。
现在客户端、服务器两边都拿到三份材料:
Client Random + Server Random + Pre‑Master‑Secret双方用完全一样的伪随机函数PRF,独立计算出相同的会话密钥 Session‑Key。
- 双方发送
ChangeCipherSpec:通知对方,后续报文全部切换为加密模式。 - 互相发送
Finished(第一条被会话密钥加密的消息 ),里面是全部握手消息的哈希摘要。- 客户端收到服务器Finished:用会话密钥解密,校验握手消息没有被篡改。
- 服务器收到客户端Finished:同样解密校验。
- TLS握手完成!
握手之后:业务数据加解密
握手结束,两端拥有完全相同的会话密钥(对称密钥AES)。
- 客户端发HTTP请求:HTTP明文交给TLS层,会话密钥加密 → 密文通过TCP发出。
- 服务器收到密文:用同一个会话密钥解密,还原出原始HTTP请求,执行业务。
- 服务器返回HTTP响应:同样会话密钥加密密文返回;客户端解密拿到HTTP响应。
整个HTTP的请求头、请求体、响应全部被加密;抓包只能看到密文。
RSA模式的弱点 & ECDHE改进
上面流程是RSA密钥交换:PMS被公钥加密传输。
- 隐患:如果服务器私钥泄露,历史所有抓取的密文全部可以被解密。
ECDHE(临时椭圆 Diffie‑Hellman)
- 不再传输PMS;双方交换临时公钥,两边本地算出共享秘密。
- 每一次握手都生成全新临时密钥;就算服务器长期私钥泄露,历史通信记录无法解密,具备前向安全性。
TLS1.3默认使用ECDHE,握手RTT进一步降低,只需要1‑RTT(Round‑Trip Time 往返时间)。具体如下:
(1)客户端在第一个 Client Hello 里面,直接带上自己的 ECDHE 临时公钥。
(2)服务端收到,立刻算出共享秘密,返回 Server Hello + 证书 + 临时公钥 + Finished。
(3)客户端收到回复,握手完成,马上就可以发 HTTP 业务数据。
客户端计算共享秘密 = C‑pri × S‑pub服务端计算共享秘密 = S‑pri × C‑pub
两边算出来的结果完全一模一样,这个结果叫ECDH 共享秘密
ECDHE 模式:不再网络传输 PMS!PMS 就是双方本地算出来的 ECDH 共享秘密。
TLS1.3简要变化
- 砍掉大量不安全加密套件;
- 握手由TLS1.2的2‑RTT缩短到 1‑RTT;
- 不再支持RSA密钥交换,全部ECDHE;
- Finished消息全部加密,不再暴露更多明文握手字段。
关键提醒
- PMS在网络上是密文,不会裸奔传输
- 会话密钥不会在网络传输,两端本地分别计算
- 非对称加密只用来保护PMS;业务流量用对称会话密钥
- 客户端:请求发起方(浏览器、APP、Java HTTP 调用方);
- 服务端:提供接口 / 网站的 Nginx/Tomcat 服务器。单向 HTTPS 握手,服务端持有公私钥对,客户端拿到服务端公钥用来加密 PMS。
- ❌错误:HTTPS全程非对称加密。✅正确:握手非对称;业务传输对称加密。
- ❌错误:证书用来加密数据。✅正确:证书主要做身份认证,提供服务器公钥。
- ❌中间人拿到证书就可以篡改通信:证书由CA签名,中间人无法伪造合法证书。
- 会话密钥是每次连接临时生成,不是证书里面的公钥私钥。