TLS/SSL加密流程
TLS/SSL 实战 包含Python代码 https://blog.csdn.net/qq_45062700/article/details/156274384
服务器 单向加密
所有节点 客户端 服务器 CA服务器 所有节点 客户端 服务器 CA服务器 CA证书生成阶段 服务器证书申请阶段 客户端准备阶段 TLS握手阶段 启动服务器 启动客户端 密钥交换阶段(非对称加密) 计算会话密钥 验证阶段 应用数据传输(对称加密) alt [证书验证失败] [证书验证成功] 1. 生成CA私钥(ca.key) 2. 生成CA根证书(ca.crt) 包含:CA公钥 + 身份信息 + CA自签名 3. 生成服务器私钥(server.key) 4. 生成CSR请求文件(server.csr) 包含:服务器公钥 + 身份信息 + 服务器私钥签名 5. 发送server.csr请求证书 6. 使用ca.key签名server.csr 生成服务器证书(server.crt) 包含:服务器公钥 + 身份信息 + CA签名 7. 返回server.crt 9. 下载CA根证书(ca.crt) 8. 启动TCP服务器 加载:server.key和server.crt 10. 启动TCP客户端 加载:ca.crt ClientHello 支持协议版本、加密套件、随机数C ServerHello 选择协议版本、加密套件、随机数S + 服务器证书(server.crt) 使用ca.crt验证server.crt失败 中止连接 使用ca.crt验证server.crt成功 提取服务器公钥 生成预主密钥(Pre-Master Secret) ClientKeyExchange 使用服务器公钥加密预主密钥 使用server.key解密预主密钥 使用随机数C、随机数S、预主密钥 计算主密钥 → 会话密钥 使用随机数C、随机数S、预主密钥 计算主密钥 → 会话密钥 ChangeCipherSpec 准备使用会话密钥 计算Finished消息 使用会话密钥加密 Finished消息(Key1) ChangeCipherSpec 解密并验证Finished消息 计算Finished消息 使用会话密钥加密 Finished消息(Key2) 解密并验证Finished消息 加密的应用数据 使用会话密钥 加密的应用数据 使用会话密钥
我的理解
CA服务器\] \[服务器\] \[客户端
-
CA服务器\]CA生成秘钥
3.[服务器]服务器生成秘钥
4.[服务器]服务器生成请求证书签名文件(包含服务器公钥)
5.[服务器]把请求证书签名文件发送给CA服务器
6.[CA服务器]CA服务器根据CA秘钥和请求证书签名文件 生成 服务器证书(包含服务器公钥)
7.[服务器]服务器下载CA颁发的服务器证书
8.[服务器]服务器启动TCP服务器,使用服务器秘钥和服务器证书
9.[客户端]客户端下载CA根证书
10.[客户端]客户端TCP启动使用使用CA根证书
通讯
1.[客户端]客户端请求连接服务器,并且告诉服务器支持的加密方式
2.[服务器] 选择一种加密方式,把服务器证书和加密方式一起发送给客户端
3.[客户端]客户端通过CA根证书验证服务器证书,错误直接返回异常
非对称加密:
4.[客户端]通过服务器公钥加密一个随机秘钥,发送给服务器
5.[服务器]通过服务器秘钥解密内容,拿到随机秘钥
对称加密:
6.[服务器]通过选择的加密方式来加密(数据内容+随机秘钥)生成一个验证的key1。 发送验证的key1和数据内容
7.[客户端]通过选择的加密方式来加密(数据内容+随机秘钥)生成一个验证的key2。 来验证key1==key2,确保内容没有被修改
8.后续都是对称加密
重要修正说明
- 证书验证时机:证书在ServerHello消息中就发送了,不是在密钥交换之后
- 预主密钥(Pre-Master Secret):这是TLS标准术语,比"随机秘钥"更准确
- 会话密钥计算 :
- 客户端和服务器独立计算,使用相同的输入:随机数C + 随机数S + 预主密钥
- 主密钥 → 会话密钥(可能包含多个密钥:加密密钥、MAC密钥、IV等)
- Finished消息验证 :
- 双方交换加密的Finished消息,而不是比较key1==key2
- Finished消息包含之前所有握手消息的哈希值,确保握手完整性
- ChangeCipherSpec消息 :
- 这是一个单独的协议消息,表示后续消息将使用协商的加密参数
- 对称加密实际使用 :
- 双方使用相同的会话密钥进行对称加密
- 通常使用AEAD(认证加密)模式,同时提供加密和完整性保护
补充的文件列表
| 文件 | 描述 | 包含内容 |
|---|---|---|
| ca.key | CA私钥 | RSA私钥,CA签名使用 |
| ca.crt | CA根证书 | CA公钥 + CA身份信息 + CA自签名 |
| server.key | 服务器私钥 | RSA私钥,服务器解密使用 |
| server.csr | 证书签名请求 | 服务器公钥 + 服务器身份信息 + 服务器私钥签名 |
| server.crt | 服务器证书 | 服务器公钥 + 服务器身份信息 + CA签名 |
这个流程图准确地反映了TLS/SSL握手过程,包含了证书验证、密钥交换和会话建立的完整流程。
双向加密
服务器 客户端 服务器 客户端 1. 客户端发起握手 2. 服务器响应 关键区别:服务器要求客户端证书 3. 客户端响应 客户端生成预主密钥 用服务器公钥加密 4. 证书验证阶段(双向验证) 5. 切换密码规范 6. 服务器完成握手 7. 客户端验证完成 8. 安全通信建立 ClientHello - TLS版本 - 支持的加密套件 - 客户端随机数 - 会话ID(可选) ServerHello - 选择的TLS版本 - 选择的加密套件 - 服务器随机数 - 会话ID(可选) Certificate - 服务器证书链(server.crt) CertificateRequest - 可接受的CA列表 - 证书类型 ServerKeyExchange (可选) - 密钥交换参数 ServerHelloDone Certificate - 客户端证书链(client.crt) 生成预主密钥(Pre-Master Secret) 使用服务器公钥加密预主密钥 ClientKeyExchange - 加密的预主密钥 验证服务器证书 使用CA根证书(ca.crt)验证server.crt CertificateVerify - 用客户端私钥(client.key)签名握手消息 证明拥有客户端证书对应的私钥 ChangeCipherSpec 表示后续使用协商的加密参数 Finished - 加密的握手消息摘要(Key1) 使用会话密钥加密 验证客户端证书 使用CA根证书(ca.crt)验证client.crt 验证CertificateVerify签名 使用客户端公钥验证签名 用服务器私钥(server.key)解密预主密钥 计算会话密钥 使用:客户端随机数 + 服务器随机数 + 预主密钥 ChangeCipherSpec Finished - 加密的握手消息摘要(Key2) 使用会话密钥加密 验证Finished消息(Key2) 确保握手完整性 计算会话密钥 使用:客户端随机数 + 服务器随机数 + 预主密钥 加密的应用数据 使用会话密钥(对称加密) 加密的应用数据 使用会话密钥(对称加密)
CA准备
生成CA密钥对 ca.key/ca.crt
服务器准备
生成服务器密钥对 server.key/server.csr
向CA申请服务器证书
获取服务器证书 server.crt
客户端准备
生成客户端密钥对 client.key/client.csr
向CA申请客户端证书
获取客户端证书 client.crt
分发CA证书
服务器获取ca.crt用于验证客户端
客户端获取ca.crt用于验证服务器
服务器配置
加载:server.key, server.crt, ca.crt
客户端配置
加载:client.key, client.crt, ca.crt