HTTPS是什么?原理是什么?用公钥加密为什么不能用公钥解密?

摘要:从一次"抓包发现HTTPS的密文竟然能被解密"的惊人发现出发,深度剖析HTTPS加密通信的完整原理。通过对称加密与非对称加密的区别、TLS握手的四次往返、以及数字证书的验证机制,揭秘为什么需要两种加密方式、中间人攻击如何防范、以及为什么公钥加密只能私钥解密。配合时序图展示密钥协商过程,给出HTTPS性能优化的最佳实践。


💥 翻车现场

周五下午,哈吉米在学习网络安全。

哈吉米(抓包):"我用Wireshark抓HTTPS的包,看看加密后的数据是什么样的……"

抓包结果

TLS Record:
- Content Type: Application Data(应用数据)
- Version: TLS 1.2
- Length: 1234
- Encrypted Data: 2f 3a 8b 9c ... (一堆乱码)

哈吉米:"全是乱码,看不懂,说明加密了 ✅"

但是……配置了Wireshark的密钥后

解密后的数据:
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json

{"username":"admin","password":"123456"}

哈吉米(震惊):"卧槽,HTTPS加密的数据竟然能被Wireshark解密?HTTPS不安全吗?"

南北绿豆和阿西噶阿西来了。

南北绿豆:"你配置了什么密钥?"
哈吉米:"服务器的私钥……"
阿西噶阿西:"那就对了!有了私钥当然能解密,这不是HTTPS不安全,而是你拿到了私钥。"
哈吉米:"那HTTPS到底是怎么加密的?为什么需要公钥和私钥?"
南北绿豆:"来,我给你讲讲HTTPS的完整原理。"


🤔 为什么需要HTTPS?HTTP有什么问题?

HTTP的3大风险

阿西噶阿西在白板上写下HTTP的问题。

HTTP是明文传输:

场景:用户登录
POST /login HTTP/1.1
Host: www.bank.com

{"username":"alice","password":"123456"}

问题1:窃听(Eavesdropping)
- 中间人(路由器、代理)能看到明文
- 密码泄露 ❌

问题2:篡改(Tampering)
- 中间人修改数据
- 把转账金额100改成10000 ❌

问题3:冒充(Impersonation)
- 中间人伪造服务器
- 用户连接到假网站 ❌

HTTPS的解决方案

问题HTTPS解决方案
窃听加密(无法看到明文)
篡改完整性校验(MAC)
冒充数字证书(验证服务器身份)

🎯 对称加密 vs 非对称加密

对称加密(Symmetric Encryption)

定义:加密和解密用同一个密钥

加密:
明文 + 密钥 → 密文

解密:
密文 + 密钥 → 明文

示例(AES):
明文:"hello"
密钥:"abc123"
加密:encrypt("hello", "abc123") → "2f3a8b9c"
解密:decrypt("2f3a8b9c", "abc123") → "hello"

优点

  • ✅ 速度快(1000倍快于非对称加密)

缺点

  • ❌ 密钥分发问题(如何安全地传递密钥?)

问题场景

客户端和服务器通信:
1. 客户端和服务器约定密钥:"abc123"
2. 如何把密钥传给对方?
   - 明文传输 → 被窃听 ❌
   - 加密传输 → 用什么加密?(鸡生蛋蛋生鸡)

非对称加密(Asymmetric Encryption)

定义:加密和解密用不同的密钥

密钥对:
- 公钥(Public Key):公开,任何人都能获取
- 私钥(Private Key):私密,只有服务器持有

加密规则:
公钥加密 → 只能私钥解密
私钥加密 → 只能公钥解密(签名)

示例(RSA):
明文:"hello"
公钥:publicKey
私钥:privateKey

公钥加密:
encrypt("hello", publicKey) → "9f2b4c5d"
只能私钥解密:
decrypt("9f2b4c5d", privateKey) → "hello"

如果用公钥解密:
decrypt("9f2b4c5d", publicKey) → 失败 ❌

为什么公钥加密不能用公钥解密?

南北绿豆:"这是数学原理决定的!"

RSA算法原理(简化):

密钥生成:
1. 选择两个大质数:p=61, q=53
2. 计算n = p × q = 3233
3. 计算φ(n) = (p-1) × (q-1) = 3120
4. 选择公钥e = 17(与φ(n)互质)
5. 计算私钥d = e^(-1) mod φ(n) = 2753

公钥:(e=17, n=3233)
私钥:(d=2753, n=3233)

加密:
密文 = 明文^e mod n

解密:
明文 = 密文^d mod n

关键:
- 公钥e和私钥d是数学上的"逆运算"
- 知道e,很难算出d(需要分解n=p×q,质因数分解很难)
- 所以公钥加密,只能私钥解密

如果用公钥"解密":
明文' = 密文^e mod n
→ 得到的是另一个密文,不是明文 ❌

哈吉米:"所以公钥加密不能公钥解密,是数学原理决定的!"


🎯 HTTPS的加密流程

为什么用两种加密?

问题

如果只用非对称加密:
- 优点:不用担心密钥分发
- 缺点:太慢(比对称加密慢1000倍)

如果只用对称加密:
- 优点:很快
- 缺点:密钥如何安全传递?

HTTPS的方案

混合加密:
1. 用非对称加密传递对称密钥(解决密钥分发)
2. 用对称加密传输数据(解决性能问题)

流程:
握手阶段:
- 用非对称加密协商对称密钥

数据传输阶段:
- 用对称密钥加密所有数据

TLS握手流程(完整版)

sequenceDiagram
    participant Client as 客户端
    participant Server as 服务器

    Note over Client,Server: 阶段1:协商加密算法
    Client->>Server: 1. Client Hello<br/>支持的加密算法列表<br/>随机数random_C
    Server->>Client: 2. Server Hello<br/>选择的加密算法<br/>随机数random_S
    
    Note over Client,Server: 阶段2:证书验证
    Server->>Client: 3. Certificate<br/>服务器证书(含公钥)
    Client->>Client: 4. 验证证书<br/>CA签名、域名、有效期
    
    Note over Client,Server: 阶段3:密钥协商
    Client->>Client: 5. 生成pre-master secret
    Client->>Server: 6. Client Key Exchange<br/>用服务器公钥加密pre-master
    
    Note over Client,Server: 双方计算对称密钥
    Note over Client: master_key = PRF(random_C, random_S, pre-master)
    Note over Server: master_key = PRF(random_C, random_S, pre-master)
    
    Client->>Server: 7. Change Cipher Spec<br/>切换到加密通信
    Client->>Server: 8. Finished(加密)
    
    Server->>Client: 9. Change Cipher Spec
    Server->>Client: 10. Finished(加密)
    
    Note over Client,Server: 握手完成,后续用对称密钥加密
    
    rect rgb(144, 238, 144)
        Client->>Server: 11. 应用数据(对称加密)
        Server->>Client: 12. 应用数据(对称加密)
    end

关键点

步骤1-2:协商算法(明文)
步骤3-4:证书验证(明文,但证书有CA签名)
步骤5-6:协商密钥(用公钥加密pre-master secret)
步骤7-10:切换到加密模式
步骤11+:数据传输(对称加密,快)

密钥计算:
master_key = f(random_C, random_S, pre-master)

特点:
- random_C和random_S是明文传输的
- pre-master是用公钥加密的
- 只有服务器能解密pre-master(用私钥)
- 客户端和服务器独立计算出相同的master_key

南北绿豆:"看到了吗?握手阶段用非对称加密协商对称密钥,数据传输用对称加密!"


🎯 数字证书:防止中间人攻击

中间人攻击

问题场景

正常流程:
客户端 ↔ 服务器

中间人攻击:
客户端 ↔ 中间人 ↔ 服务器

攻击过程:
1. 客户端请求服务器公钥
2. 中间人拦截,返回自己的公钥
3. 客户端用中间人公钥加密数据
4. 中间人用自己的私钥解密(看到明文)
5. 中间人用服务器公钥加密,发给服务器
6. 服务器用自己的私钥解密

结果:
- 客户端以为在和服务器通信
- 实际在和中间人通信
- 中间人看到所有明文 ❌

数字证书的作用

解决方案:CA(Certificate Authority)证书颁发机构

证书内容:
- 域名:www.example.com
- 公钥:MIIBIjANBgk...
- 有效期:2024-01-01 到 2025-01-01
- 签发者:Let's Encrypt
- CA签名:用CA私钥签名(证明证书真实性)

验证流程:
1. 服务器发送证书(含公钥)
2. 客户端验证证书:
   - 域名是否匹配(www.example.com)
   - 有效期是否过期
   - CA签名是否正确(用CA公钥验证)
3. 验证通过 → 信任这个公钥
4. 用公钥加密数据

为什么中间人伪造不了证书?

中间人尝试伪造:
1. 生成自己的公钥/私钥
2. 制作证书(含自己的公钥)
3. 发给客户端

客户端验证:
1. 检查CA签名
2. 用CA公钥验证签名 → 验证失败 ❌
3. 证书无效,拒绝连接

原因:
- 证书必须由CA签名
- CA私钥只有CA有(严格保管)
- 中间人无法伪造CA签名

CA信任链

CA(Root CA)
  ├─ 中间CA1
     ├─ Let's Encrypt
        └─ www.example.com的证书
     └─ DigiCert
  └─ 中间CA2

验证流程:
1. 客户端有根CA的公钥(内置在浏览器/操作系统)
2. 验证中间CA的证书(用根CA公钥)
3. 验证Let's Encrypt的证书(用中间CA公钥)
4. 验证www.example.com的证书(用Let's Encrypt公钥)
5. 信任链完整  信任服务器公钥 

🎯 对称加密 vs 非对称加密对比

性能对比

加密100MB数据:

对称加密(AES-256):
- 耗时:0.5秒
- 速度:200MB/s

非对称加密(RSA-2048):
- 耗时:500秒
- 速度:0.2MB/s

性能差距:1000倍

对比表

特性对称加密(AES)非对称加密(RSA)
密钥1个(加密解密用同一个)2个(公钥私钥)
速度⭐⭐⭐⭐⭐ 极快⭐ 慢
密钥分发❌ 难(如何传递密钥)✅ 易(公钥公开)
适用大量数据加密密钥交换、签名
示例AES、DES、3DESRSA、ECC

HTTPS的策略

握手阶段(少量数据):
用非对称加密(协商对称密钥)

数据传输阶段(大量数据):
用对称加密(快)

🎯 公钥加密为什么不能公钥解密?

数学原理

南北绿豆:"这是数学上的单向函数。"

非对称加密的数学基础:

公钥加密 = f(明文, 公钥)
私钥解密 = f^(-1)(密文, 私钥)

关键:
- f 是"单向陷门函数"
- 知道公钥,正向计算容易(加密)
- 不知道私钥,反向计算困难(解密)

类比:
正向:9 × 7 = 63(容易)
反向:63 = ? × ?(质因数分解,困难)

RSA的安全性:
基于"大整数质因数分解"很难
n = p × qpq是大质数)
知道n,很难分解出pq

加密方向

公钥加密,私钥解密(保密):

用途:加密通信

流程:
1. 客户端用服务器公钥加密数据
2. 只有服务器能解密(用私钥)
3. 其他人拿到密文,没有私钥,无法解密 ✅

私钥加密,公钥解密(签名):

用途:数字签名(证明身份)

流程:
1. 服务器用私钥加密数据(签名)
2. 任何人都能用公钥解密
3. 解密成功 → 证明数据确实来自服务器(私钥只有服务器有)
4. 验证身份 ✅

示例:
服务器:"我是www.example.com"
签名:encrypt("我是www.example.com", 私钥)

客户端验证:
decrypt(签名, 公钥) == "我是www.example.com" → 身份验证成功 ✅

🎯 HTTPS的完整加密过程

密钥协商

步骤1:客户端生成随机数random_C(明文发送)
步骤2:服务器生成随机数random_S(明文发送)
步骤3:客户端生成pre-master secret
步骤4:客户端用服务器公钥加密pre-master secret
步骤5:发送给服务器(密文)
步骤6:服务器用私钥解密,得到pre-master secret

步骤7:双方计算对称密钥
master_key = PRF(random_C, random_S, pre-master)

步骤8:后续用master_key加密所有数据

为什么需要3个随机数?

安全性:
- random_C:客户端生成(防止重放攻击)
- random_S:服务器生成(防止重放攻击)
- pre-master:客户端生成(增加随机性)

组合:
- 3个随机数混合
- 计算出的master_key随机性强
- 每次握手的密钥都不同 ✅

🎯 HTTPS的性能优化

优化1:会话复用(Session Resumption)

问题:
每次连接都要完整握手(4次往返)

优化:
第1次握手:
- 完整TLS握手(4-RTT)
- 服务器返回Session ID

第2次连接(1小时内):
- 客户端带上Session ID
- 服务器验证Session ID
- 跳过密钥协商
- 只需1-RTT

性能提升:
握手时间从4-RTT降到1-RTT(快3倍)

优化2:TLS 1.3(0-RTT)

TLS 1.2:
- 握手:4-RTT
- 耗时:200ms(RTT=50ms)

TLS 1.3:
- 首次握手:1-RTT
- 后续:0-RTT(携带上次密钥)
- 耗时:0-50ms

性能提升:
握手时间从200ms降到0-50ms(快4-8倍)

🎓 面试标准答案

题目:HTTPS的原理是什么?

答案

HTTPS = HTTP + TLS(加密层)

核心流程

1. TLS握手(密钥协商)

  • 客户端发送支持的加密算法
  • 服务器选择算法,发送证书(含公钥)
  • 客户端验证证书
  • 客户端生成pre-master secret,用公钥加密发送
  • 双方计算对称密钥(master_key)

2. 数据传输(对称加密)

  • 用master_key加密所有数据
  • 快速传输

加密方式

  • 握手:非对称加密(协商密钥)
  • 数据:对称加密(快速传输)

为什么混合加密

  • 非对称加密:解决密钥分发问题
  • 对称加密:解决性能问题

证书作用

  • 证明服务器身份
  • 防止中间人攻击
  • 提供公钥

题目:用公钥加密为什么不能用公钥解密?

答案

数学原理决定的

非对称加密

  • 公钥和私钥是数学上的"配对"
  • 公钥加密 = f(明文, 公钥)
  • 私钥解密 = f^(-1)(密文, 私钥)
  • f 是单向陷门函数

RSA示例

  • 加密:密文 = 明文^公钥 mod n
  • 解密:明文 = 密文^私钥 mod n

为什么不能公钥解密

  • 公钥解密 = 密文^公钥 mod n
  • 得到的不是明文,而是另一个密文
  • 数学上不是逆运算

两个方向

  • 公钥加密 → 私钥解密(保密)
  • 私钥加密 → 公钥解密(签名)

🎉 结束语

晚上10点,哈吉米终于理解了HTTPS的原理。

哈吉米:"原来HTTPS用了混合加密:握手用非对称加密协商密钥,数据传输用对称加密!"

南北绿豆:"对,非对称加密解决密钥分发问题,对称加密解决性能问题。"

阿西噶阿西:"记住:公钥加密只能私钥解密,这是数学原理决定的。"

哈吉米:"还有数字证书,通过CA签名验证服务器身份,防止中间人攻击。"

南北绿豆:"对,理解了HTTPS的原理,就知道为什么它是安全的!"


记忆口诀

HTTPS等于HTTP加TLS,混合加密保安全
握手阶段非对称加密,协商对称密钥
数据传输对称加密,速度快性能好
公钥加密私钥解密,数学原理保安全
数字证书CA签名,防止中间人攻击