264 lines
8.1 KiB
Markdown
264 lines
8.1 KiB
Markdown
# SSL安全配置说明
|
||
|
||
## 当前SSL配置
|
||
|
||
### 服务器端配置(Server/main.cpp)
|
||
```cpp
|
||
static const int g_s_iVerifyMode = SSL_VM_PEER | SSL_VM_FAIL_IF_NO_PEER_CERT;
|
||
```
|
||
|
||
**配置说明:**
|
||
- `SSL_VM_PEER`:要求验证对方(客户端)的证书
|
||
- `SSL_VM_FAIL_IF_NO_PEER_CERT`:如果客户端没有提供证书,连接失败
|
||
- 服务器配置了CA证书(`g_s_lpszCAPemCert`)用于验证客户端证书的有效性
|
||
|
||
**安全特性:**
|
||
✅ 要求客户端必须提供合法证书
|
||
✅ 验证客户端证书是否由可信CA签发
|
||
✅ 防止未授权客户端连接
|
||
✅ 实现双向身份认证(Mutual TLS)
|
||
|
||
### 客户端配置(Client/main.cpp)
|
||
```cpp
|
||
static const int g_c_iVerifyMode = SSL_VM_PEER;
|
||
```
|
||
|
||
**配置说明:**
|
||
- `SSL_VM_PEER`:要求验证对方(服务器)的证书
|
||
- 客户端配置了CA证书(`g_c_lpszCAPemCert`)用于验证服务器证书的有效性
|
||
|
||
**安全特性:**
|
||
✅ 验证服务器证书的合法性
|
||
✅ 确保连接到正确的服务器
|
||
✅ 防止中间人攻击(MITM)
|
||
✅ 防止服务器伪造
|
||
|
||
## SSL验证模式对比
|
||
|
||
### 1. SSL_VM_NONE(已弃用)
|
||
```cpp
|
||
static const int g_s_iVerifyMode = SSL_VM_NONE; // 旧配置
|
||
```
|
||
- ⚠️ 不验证对方证书
|
||
- ⚠️ 提供加密但不提供身份认证
|
||
- ⚠️ 易受中间人攻击
|
||
- ⚠️ 任何人都可以伪造服务器
|
||
- ❌ 不推荐用于生产环境
|
||
|
||
### 2. SSL_VM_PEER(当前配置)
|
||
```cpp
|
||
static const int g_c_iVerifyMode = SSL_VM_PEER; // 客户端配置
|
||
```
|
||
- ✅ 验证对方证书的有效性
|
||
- ✅ 检查证书是否由可信CA签发
|
||
- ✅ 提供加密 + 身份认证
|
||
- ✅ 防止中间人攻击
|
||
- ✅ 适合生产环境
|
||
|
||
### 3. SSL_VM_PEER + SSL_VM_FAIL_IF_NO_PEER_CERT(当前配置)
|
||
```cpp
|
||
static const int g_s_iVerifyMode = SSL_VM_PEER | SSL_VM_FAIL_IF_NO_PEER_CERT; // 服务器配置
|
||
```
|
||
- ✅ 强制要求对方提供证书
|
||
- ✅ 如果对方未提供证书,连接失败
|
||
- ✅ 实现严格的双向认证
|
||
- ✅ 最高级别的安全保护
|
||
- ✅ 适合高安全要求的生产环境
|
||
|
||
## 证书配置
|
||
|
||
### 证书文件说明
|
||
当前项目中内置了以下证书(嵌入在源码中):
|
||
|
||
1. **服务器证书** (`g_s_lpszPemCert`)
|
||
- 用于服务器向客户端证明身份
|
||
- 包含服务器的公钥
|
||
- 由CA签发
|
||
|
||
2. **服务器私钥** (`g_s_lpszPemKey`)
|
||
- 服务器的私钥(加密)
|
||
- 密码:`123456`
|
||
- 用于解密和签名
|
||
|
||
3. **客户端证书** (`g_c_lpszPemCert`)
|
||
- 用于客户端向服务器证明身份
|
||
- 包含客户端的公钥
|
||
- 由CA签发
|
||
|
||
4. **客户端私钥** (`g_c_lpszPemKey`)
|
||
- 客户端的私钥(加密)
|
||
- 密码:`123456`
|
||
- 用于解密和签名
|
||
|
||
5. **CA证书** (`g_s_lpszCAPemCert` / `g_c_lpszCAPemCert`)
|
||
- 证书颁发机构的根证书
|
||
- 用于验证对方证书的合法性
|
||
- 双方使用相同的CA证书
|
||
|
||
### 证书验证流程
|
||
|
||
#### 客户端连接服务器时:
|
||
1. **服务器向客户端发送自己的证书**
|
||
- 客户端接收服务器证书
|
||
- 客户端使用CA证书验证服务器证书的有效性
|
||
- 验证证书签名是否由可信CA签发
|
||
- 验证证书是否在有效期内
|
||
- ✅ 验证通过,客户端信任服务器
|
||
|
||
2. **客户端向服务器发送自己的证书**
|
||
- 服务器接收客户端证书
|
||
- 服务器使用CA证书验证客户端证书的有效性
|
||
- 因为配置了 `SSL_VM_FAIL_IF_NO_PEER_CERT`,如果客户端不提供证书,连接失败
|
||
- ✅ 验证通过,服务器信任客户端
|
||
|
||
3. **建立加密通道**
|
||
- 双方完成身份认证
|
||
- 建立安全的加密通信通道
|
||
- 后续所有数据都经过加密传输
|
||
|
||
## 安全优势
|
||
|
||
### 当前配置的安全等级:🔒 高度安全
|
||
|
||
1. **双向身份认证**
|
||
- 服务器验证客户端身份
|
||
- 客户端验证服务器身份
|
||
- 防止任何一方伪造
|
||
|
||
2. **数据加密**
|
||
- 所有通信数据经过TLS/SSL加密
|
||
- 使用强加密算法
|
||
- 防止数据窃听
|
||
|
||
3. **防止中间人攻击**
|
||
- 证书验证确保连接到正确的对方
|
||
- 无法在中间插入恶意代理
|
||
- 无法篡改传输数据
|
||
|
||
4. **访问控制**
|
||
- 只有持有合法证书的客户端才能连接
|
||
- 实现基于证书的访问控制
|
||
- 适合机器码授权等场景
|
||
|
||
## 生产环境建议
|
||
|
||
### 证书管理
|
||
1. **不要在源码中硬编码证书**(当前演示用)
|
||
- 生产环境应从文件或安全存储加载证书
|
||
- 使用 `SetupSSLContext()` 代替 `SetupSSLContextByMemory()`
|
||
|
||
2. **保护私钥安全**
|
||
- 私钥密码不要使用简单密码
|
||
- 考虑使用硬件安全模块(HSM)
|
||
- 定期轮换证书和密钥
|
||
|
||
3. **使用正规CA证书**
|
||
- 当前是自签名证书(仅用于演示)
|
||
- 生产环境建议使用正规CA签发的证书
|
||
- 或搭建企业内部PKI体系
|
||
|
||
### 代码示例:从文件加载证书
|
||
```cpp
|
||
// 推荐:从文件加载证书
|
||
if (!server->SetupSSLContext(
|
||
g_s_iVerifyMode, // 验证模式
|
||
"server-cert.pem", // 服务器证书文件路径
|
||
"server-key.pem", // 服务器私钥文件路径
|
||
g_s_lpszKeyPassword, // 私钥密码
|
||
"ca-cert.pem")) // CA证书文件路径
|
||
{
|
||
// 错误处理
|
||
}
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
### Q: 为什么需要CA证书?
|
||
A: CA证书用于验证对方证书的合法性。就像身份证需要公安局盖章一样,SSL证书也需要CA签名才能被信任。
|
||
|
||
### Q: 客户端证书和服务器证书有什么区别?
|
||
A: 技术上没有本质区别,都是X.509证书。区别在于用途:
|
||
- 服务器证书:证明服务器身份
|
||
- 客户端证书:证明客户端身份
|
||
|
||
### Q: SSL_VM_PEER和SSL_VM_NONE有什么区别?
|
||
A:
|
||
- **SSL_VM_NONE**:只加密,不验证身份(类似:对话加密了,但不知道对方是谁)
|
||
- **SSL_VM_PEER**:加密+验证身份(类似:对话加密了,并且验证了对方身份证)
|
||
|
||
### Q: 为什么服务器要用SSL_VM_FAIL_IF_NO_PEER_CERT?
|
||
A: 这是最严格的验证模式,强制要求客户端必须提供证书。适合需要高安全性的场景,例如:
|
||
- 金融交易系统
|
||
- 机器码授权系统
|
||
- 企业内部系统
|
||
- 需要严格访问控制的服务
|
||
|
||
### Q: 当前配置是否足够安全?
|
||
A: 当前配置提供了TLS/SSL的最高安全等级:
|
||
- ✅ 双向认证(Mutual TLS)
|
||
- ✅ 数据加密
|
||
- ✅ 防中间人攻击
|
||
- ✅ 防伪造服务器/客户端
|
||
|
||
但请注意:
|
||
- ⚠️ 证书硬编码在源码中(仅适合演示)
|
||
- ⚠️ 使用自签名证书(生产环境建议使用正规CA证书)
|
||
- ⚠️ 私钥密码过于简单(生产环境应使用复杂密码)
|
||
|
||
## 测试验证
|
||
|
||
### 验证SSL配置
|
||
运行程序后,观察日志输出:
|
||
```
|
||
[服务器] 正在初始化SSL环境...
|
||
[服务器] SSL环境初始化成功
|
||
[服务器] 服务器启动成功,监听端口: 5555
|
||
|
||
[客户端] 正在初始化SSL环境...
|
||
[客户端] SSL环境初始化成功
|
||
[客户端] 正在连接服务器 127.0.0.1:5555 ...
|
||
[客户端] OnHandShake - SSL握手完成!ID=1
|
||
[客户端] 已连接到服务器,可以开始发送消息
|
||
```
|
||
|
||
如果看到 "SSL握手完成",说明双向认证成功!
|
||
|
||
### 修改验证模式测试
|
||
可以尝试修改配置来测试不同场景:
|
||
|
||
1. **测试:客户端不提供证书**
|
||
```cpp
|
||
// 修改服务器配置,去掉FAIL_IF_NO_PEER_CERT
|
||
static const int g_s_iVerifyMode = SSL_VM_PEER; // 允许客户端不提供证书
|
||
```
|
||
|
||
2. **测试:不验证证书**
|
||
```cpp
|
||
// 修改为不验证(不推荐)
|
||
static const int g_c_iVerifyMode = SSL_VM_NONE; // 客户端不验证服务器
|
||
```
|
||
|
||
## 总结
|
||
|
||
当前项目已经配置为 **SSL_VM_PEER + 双向认证** 模式,这是SSL/TLS提供的最高安全级别。
|
||
|
||
**配置概要:**
|
||
- ✅ 服务器验证客户端证书(SSL_VM_PEER | SSL_VM_FAIL_IF_NO_PEER_CERT)
|
||
- ✅ 客户端验证服务器证书(SSL_VM_PEER)
|
||
- ✅ 双方使用CA证书验证对方
|
||
- ✅ 所有数据加密传输
|
||
- ✅ 防止中间人攻击
|
||
- ✅ 防止服务器/客户端伪造
|
||
|
||
**适用场景:**
|
||
- 高安全要求的通信系统
|
||
- 机器码授权和许可证管理
|
||
- 企业内部加密通信
|
||
- 金融交易系统
|
||
- 任何需要双向身份认证的场景
|
||
|
||
---
|
||
**编译日期:** 2026年1月13日
|
||
**HP-Socket版本:** 6.0.7
|
||
**SSL配置:** VM_PEER + 双向认证(Mutual TLS)
|