SSL 协议

SSL 协议详解

SSL(Secure Sockets Layer,安全套接字层)是网络安全通信的早期协议,由Netscape在1990年代开发,后来演进为TLS(Transport Layer Security)。SSL为TCP连接提供加密、认证和数据完整性保护。

1. SSL 协议历史和演进

版本演进

版本发布年份开发者状态RFC
SSL 1.01994Netscape未发布
SSL 2.01995Netscape已废弃
SSL 3.01996Netscape已废弃RFC 6101
TLS 1.01999IETF已废弃RFC 2246
TLS 1.12006IETF已废弃RFC 4346
TLS 1.22008IETF常用RFC 5246
TLS 1.32018IETF推荐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字节

内容类型

类型说明
ChangeCipherSpec20更改密码规范
Alert21警告消息
Handshake22握手消息
Application23应用数据

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.0RC4-MD5RSARC4MD5极低
SSL 3.0TLS_RSA_WITH_RC4_128_MD5RSARC4MD5
TLS 1.0TLS_RSA_WITH_AES_128_CBC_SHARSAAES-CBCHMAC-SHA1
TLS 1.2TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384ECDHE+RSAAES-GCM内置
TLS 1.3TLS_AES_256_GCM_SHA384ECDHEAES-GCM内置最高

TLS 1.3 密码套件(简化)

套件密钥交换加密认证
TLS_AES_128_GCM_SHA256ECDHEAES-128-GCMSHA256
TLS_AES_256_GCM_SHA384ECDHEAES-256-GCMSHA384
TLS_CHACHA20_POLY1305_SHA256ECDHEChaCha20-Poly1305SHA256

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 证书验证

  1. 链验证:完整证书链到信任根
  2. 签名验证:上级CA公钥验证
  3. 有效期:notBefore ≤ now ≤ notAfter
  4. 主体匹配:CN/SAN匹配主机名
  5. 密钥用法:符合KeyUsage扩展
  6. 吊销检查:OCSP/CRL

证书扩展

扩展作用
SubjectAltName多域名支持
KeyUsage密钥用途限制
ExtendedKeyUsage扩展用途
OCSP Stapling证书状态缓存
SCTCertificate 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通过简化握手、强制前向保密和集成认证,提供了最高安全级别,是现代安全通信的标准协议。正确配置和持续更新是确保通信安全的关键。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注