SSL 协议详解
SSL(Secure Sockets Layer,安全套接字层)是网络安全通信的早期协议,由Netscape在1990年代开发,后来演进为TLS(Transport Layer Security)。SSL为TCP连接提供加密、认证和数据完整性保护。
1. SSL 协议历史和演进
版本演进
版本 | 发布年份 | 开发者 | 状态 | RFC |
---|
SSL 1.0 | 1994 | Netscape | 未发布 | – |
SSL 2.0 | 1995 | Netscape | 已废弃 | – |
SSL 3.0 | 1996 | Netscape | 已废弃 | RFC 6101 |
TLS 1.0 | 1999 | IETF | 已废弃 | RFC 2246 |
TLS 1.1 | 2006 | IETF | 已废弃 | RFC 4346 |
TLS 1.2 | 2008 | IETF | 常用 | RFC 5246 |
TLS 1.3 | 2018 | IETF | 推荐 | RFC 8446 |
废弃原因
- SSL 2.0:严重漏洞(截断攻击、弱加密)
- SSL 3.0:POODLE攻击、弱密码套件
- TLS 1.0/1.1:BEAST、POODLE变种、弱CBC模式
2. SSL/TLS 协议架构
协议栈结构
应用层 (HTTP, SMTP, RDP等)
↓
记录协议 (Record Protocol)
├── 应用数据记录
├── 握手数据记录
├── 警告记录
└── 更改密码规范记录
↓
握手协议 (Handshake Protocol)
├── 客户端Hello
├── 服务器Hello
├── 证书交换
└── 密钥交换
↓
密码套件协商
├── 密钥交换算法
├── 加密算法
├── MAC算法
└── 认证机制
↓
传输层 (TCP)
记录协议格式
+----------+----------+----------+----------------+----------+
| Content | Protocol | Length | Data | Padding |
| Type | Version | (opaque) | (opaque type) | (opt.) |
+----------+----------+----------+----------------+----------+
| 1 | 2 | 2 | Variable | Variable |
字节 字节 字节 16384字节最大 256字节
内容类型
类型 | 值 | 说明 |
---|
ChangeCipherSpec | 20 | 更改密码规范 |
Alert | 21 | 警告消息 |
Handshake | 22 | 握手消息 |
Application | 23 | 应用数据 |
3. SSL 握手协议
SSL 2.0 握手(已废弃)
1. ClientHello: 随机数、会话ID、密码套件
2. ServerHello: 选择密码套件、证书
3. ClientMasterKey: 预主密钥(RSA加密)
4. ServerVerify: 挑战验证
5. ClientFinished/ServerFinished: 完成
SSL 3.0/TLS 1.0-1.2 完整握手
1. ClientHello
- 随机数(C_Random)
- 会话ID
- 密码套件列表
- 压缩方法
- 扩展(SNI、签名算法等)
2. ServerHello
- 选择密码套件
- 随机数(S_Random)
- 会话ID
- 压缩方法
3. Certificate*
- 服务器证书链
4. ServerKeyExchange*
- DHE/ECDHE参数(临时密钥交换)
5. CertificateRequest*
- 客户端证书请求
6. ServerHelloDone
7. Certificate*
- 客户端证书
8. ClientKeyExchange
- 预主密钥(RSA)或密钥交换参数(DHE)
9. CertificateVerify*
- 客户端证书签名
10. [ChangeCipherSpec]
11. Finished (客户端)
12. [ChangeCipherSpec]
13. Finished (服务器)
TLS 1.3 简化握手(1-RTT)
1. ClientHello
- 密码套件
- 密钥共享(ECDHE)
- PSK(可选)
2. ServerHello
- 选择密码套件
- 密钥共享
- 证书
- 证书验证
3. [加密扩展]
4. 加密应用数据
4. 密码套件(Cipher Suites)
命名格式
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
└───┬───┘└──────────┬──────────┘└──┬──┘└──┬──┘
│ │ │ │ └─PRF/哈希
│ │ │ └──────加密算法+模式
│ │ └────────────密钥交换
│ └────────────────────────认证算法
└────────────────────────────协议+密钥交换算法
历史演进
时代 | 典型套件 | 密钥交换 | 加密 | MAC | 安全 |
---|
SSL 2.0 | RC4-MD5 | RSA | RC4 | MD5 | 极低 |
SSL 3.0 | TLS_RSA_WITH_RC4_128_MD5 | RSA | RC4 | MD5 | 低 |
TLS 1.0 | TLS_RSA_WITH_AES_128_CBC_SHA | RSA | AES-CBC | HMAC-SHA1 | 中 |
TLS 1.2 | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | ECDHE+RSA | AES-GCM | 内置 | 高 |
TLS 1.3 | TLS_AES_256_GCM_SHA384 | ECDHE | AES-GCM | 内置 | 最高 |
TLS 1.3 密码套件(简化)
套件 | 密钥交换 | 加密 | 认证 |
---|
TLS_AES_128_GCM_SHA256 | ECDHE | AES-128-GCM | SHA256 |
TLS_AES_256_GCM_SHA384 | ECDHE | AES-256-GCM | SHA384 |
TLS_CHACHA20_POLY1305_SHA256 | ECDHE | ChaCha20-Poly1305 | SHA256 |
5. 密钥交换机制
RSA 密钥交换(已不推荐)
1. 客户端生成预主密钥(PMS)
2. 用服务器公钥RSA加密PMS
3. 服务器用私钥解密得到PMS
4. 双方用PMS + Random生成会话密钥
问题:无前向保密(PFS)
Diffie-Hellman 密钥交换(DHE)
p, g = 服务器DH参数
客户端: 私钥a, 公钥A = g^a mod p
服务器: 私钥b, 公钥B = g^b mod p
共享密钥: K = B^a mod p = A^b mod p
椭圆曲线DH(ECDHE,推荐)
- 更小密钥:256位EC ≈ 3072位DH
- 更高效:快速计算
- 前向保密:临时密钥对
TLS 1.3 密钥推导(HKDF)
Early Secret ← HKDF-Extract(0b, client_early_secret)
Handshake Secret ← HKDF-Extract(Early Secret, handshake_key)
Master Secret ← HKDF-Extract(Handshake Secret, app_key)
Traffic Keys ← HKDF-Expand-Label(Master Secret, "traffic")
6. 消息认证和完整性
HMAC(早期版本)
HMAC(K, seq_num || TLSCompressed.version || TLSCompressed.length ||
TLSCompressed.fragment)
AEAD(TLS 1.2+,推荐)
- AES-GCM:Galois/Counter Mode
- ChaCha20-Poly1305:流加密+认证
TLS 1.3 认证机制
- 集成认证:加密算法内置MAC
- 序列号加密:防止重放攻击
- 记录分片:每个记录独立认证
7. 证书和PKI集成
X.509 证书验证
- 链验证:完整证书链到信任根
- 签名验证:上级CA公钥验证
- 有效期:notBefore ≤ now ≤ notAfter
- 主体匹配:CN/SAN匹配主机名
- 密钥用法:符合KeyUsage扩展
- 吊销检查:OCSP/CRL
证书扩展
扩展 | 作用 |
---|
SubjectAltName | 多域名支持 |
KeyUsage | 密钥用途限制 |
ExtendedKeyUsage | 扩展用途 |
OCSP Stapling | 证书状态缓存 |
SCT | Certificate Transparency |
客户端证书认证
1. Server发送CertificateRequest
2. Client选择证书和私钥
3. Client发送Certificate和CertificateVerify
4. Server验证签名链和证书签名
8. SSL 会话恢复
会话ID(TLS 1.2)
- 服务器生成:32字节会话标识
- 客户端缓存:恢复会话状态
- 问题:服务器状态存储
会话票据(Session Tickets)
Ticket = Encryption(TLS Session State, Master Secret, Ticket Age)
- 无状态:服务器不存储会话
- 加密票据:TLS主密钥加密
- 生命周期:可配置过期时间
TLS 1.3 PSK(Pre-Shared Key)
- 外部PSK:外部密钥交换
- 恢复PSK:从票据派生
- 0-RTT:快速数据传输(有风险)
9. SSL 扩展功能
SNI(Server Name Indication)
Extension: server_name (0x0000)
Name List:
server_name: example.com
- 虚拟主机:同一IP多域名
- TLS扩展:ClientHello携带
ALPN(Application-Layer Protocol Negotiation)
Extension: application_layer_protocol_negotiation (0x0010)
Protocol: h2, http/1.1
- HTTP/2协商:协议选择
- gRPC等:应用层协议
OCSP Stapling
服务器在CertificateStatus消息中携带OCSP响应:
Handshake Message: Certificate Status
Status: OCSP Response (DER编码)
10. 著名安全漏洞
POODLE(SSL 3.0)
- Padding Oracle:CBC填充预言机
- 攻击:降级到SSL 3.0,解密Cookie
- 防护:禁用SSL 3.0
BEAST(TLS 1.0)
- CBC攻击:IV可预测
- Cookie窃取:HTTPS Cookie泄露
- 防护:TLS 1.1+,1/n-1分割
Heartbleed(OpenSSL)
- 缓冲区读取:心跳扩展漏洞
- 内存泄露:私钥、会话密钥
- 影响:OpenSSL 1.0.1-1.0.1f
CRIME/BREACH
- 压缩攻击:HTTP压缩侧信道
- Cookie窃取:通过压缩比推断
- 防护:禁用压缩,TLS 1.3无压缩
11. 现代TLS配置最佳实践
推荐配置(TLS 1.2)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_session_ticket_key_file /path/to/ticket.key;
HSTS配置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
安全头部
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'";
12. 编程实现示例
Python SSL上下文
import ssl
import socket
from http.client import HTTPSConnection
# 创建安全上下文
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED
# 自定义密码套件(TLS 1.3优先)
context.set_ciphers('TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256')
# HTTPS连接
conn = HTTPSConnection("example.com", context=context)
conn.request("GET", "/")
response = conn.getresponse()
print(response.read().decode())
conn.close()
OpenSSL命令行
# 生成自签名证书
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes
# 查看证书信息
openssl x509 -in server.crt -text -noout
# TLS连接测试
openssl s_client -connect example.com:443 \
-servername example.com \
-tls1_3 \
-cipher AES256-GCM-SHA384
# 密码套件测试
openssl s_client -connect example.com:443 -cipher 'ECDHE:!aNULL'
# OCSP查询
openssl ocsp -issuer ca.crt -cert server.crt -url http://ocsp.example.com -CAfile ca.crt
13. 性能优化
会话复用
ssl_session_cache shared:SSL:50m; # 缓存32k会话
ssl_session_timeout 1d; # 1天超时
ssl_session_tickets on; # 无状态票据
硬件加速
ssl_engine pkcs11; # 硬件加密引擎
ssl_ecdh_curve secp384r1; # 椭圆曲线
ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384;
0-RTT(TLS 1.3)
# 客户端缓存PSK
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.set_ciphers('TLS_AES_256_GCM_SHA384')
# 启用0-RTT(需谨慎)
14. 调试和诊断
常见错误
错误 | 原因 | 解决 |
---|
“handshake failure” | 密码套件不匹配 | 检查支持套件 |
“certificate verify failed” | 证书不受信任 | 更新CA,检查链 |
“unknown ca” | 根CA缺失 | 导入信任根 |
“sslv3 alert handshake failure” | 协议降级 | 禁用弱协议 |
诊断工具
# ssllabs在线测试
# https://www.ssllabs.com/ssltest/
# nmap脚本扫描
nmap --script ssl-enum-ciphers -p 443 example.com
# testssl.sh
./testssl.sh --fast example.com
# Wireshark过滤
ssl.handshake.type == 2 # ClientHello
ssl.handshake.type == 11 # Certificate
日志分析
error_log /var/log/nginx/ssl_error.log debug;
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ca.crt;
SSL/TLS协议从Netscape的SSL 1.0演进到现代TLS 1.3,经历了多次安全强化和性能优化。TLS 1.3通过简化握手、强制前向保密和集成认证,提供了最高安全级别,是现代安全通信的标准协议。正确配置和持续更新是确保通信安全的关键。