备份-基础ssl通信
This commit is contained in:
358
Client-Native/README.md
Normal file
358
Client-Native/README.md
Normal file
@@ -0,0 +1,358 @@
|
||||
# Client-Native 说明文档
|
||||
|
||||
## 项目简介
|
||||
|
||||
**Client-Native** 是一个纯OpenSSL+Winsock实现的SSL客户端,**不使用HP-Socket库**。
|
||||
|
||||
这个项目的目的是:
|
||||
1. 展示底层SSL通信的实现细节
|
||||
2. 对比HP-Socket封装的便利性
|
||||
3. 帮助理解SSL/TLS协议的工作原理
|
||||
|
||||
## 功能对比
|
||||
|
||||
### Client(使用HP-Socket)
|
||||
```cpp
|
||||
// 简单的几行代码就能实现SSL客户端
|
||||
CClientListener listener;
|
||||
CSSLClientPtr client(&listener);
|
||||
|
||||
// 初始化SSL(HP-Socket封装)
|
||||
client->SetupSSLContextByMemory(...);
|
||||
|
||||
// 连接服务器(HP-Socket封装)
|
||||
client->Start(address, port);
|
||||
|
||||
// 发送数据(HP-Socket封装)
|
||||
client->Send(data, length);
|
||||
```
|
||||
|
||||
### Client-Native(纯OpenSSL+Winsock)
|
||||
```cpp
|
||||
// 需要手动处理很多底层细节
|
||||
|
||||
// 1. 初始化Winsock
|
||||
WSAStartup(...);
|
||||
|
||||
// 2. 创建socket
|
||||
socket = socket(AF_INET, SOCK_STREAM, ...);
|
||||
|
||||
// 3. 连接服务器
|
||||
connect(socket, ...);
|
||||
|
||||
// 4. 创建SSL上下文
|
||||
SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());
|
||||
|
||||
// 5. 加载证书和私钥
|
||||
SSL_CTX_use_certificate(...);
|
||||
SSL_CTX_use_PrivateKey(...);
|
||||
|
||||
// 6. 创建SSL对象
|
||||
SSL* ssl = SSL_new(ctx);
|
||||
|
||||
// 7. 绑定socket
|
||||
SSL_set_fd(ssl, socket);
|
||||
|
||||
// 8. SSL握手
|
||||
SSL_connect(ssl);
|
||||
|
||||
// 9. 发送数据
|
||||
SSL_write(ssl, data, length);
|
||||
|
||||
// 10. 接收数据
|
||||
SSL_read(ssl, buffer, size);
|
||||
|
||||
// 11. 清理资源
|
||||
SSL_shutdown(ssl);
|
||||
SSL_free(ssl);
|
||||
closesocket(socket);
|
||||
WSACleanup();
|
||||
```
|
||||
|
||||
**结论:HP-Socket的封装极大简化了开发工作!**
|
||||
|
||||
## 实现的功能
|
||||
|
||||
### ✅ 已实现
|
||||
- Winsock初始化
|
||||
- TCP socket连接
|
||||
- SSL上下文创建和配置
|
||||
- 从内存加载证书和私钥
|
||||
- SSL双向认证(SSL_VM_PEER)
|
||||
- SSL握手
|
||||
- 加密数据发送
|
||||
- 加密数据接收
|
||||
- 非阻塞数据接收检查
|
||||
- 交互式命令界面
|
||||
- 资源清理
|
||||
|
||||
### 🎯 核心代码
|
||||
|
||||
#### 1. 初始化SSL环境
|
||||
```cpp
|
||||
bool InitializeSSL()
|
||||
{
|
||||
// 创建SSL上下文
|
||||
g_ssl_ctx = SSL_CTX_new(TLS_client_method());
|
||||
|
||||
// 设置验证模式
|
||||
SSL_CTX_set_verify(g_ssl_ctx, SSL_VERIFY_PEER, nullptr);
|
||||
|
||||
// 加载CA证书
|
||||
X509* ca_cert = LoadCertFromMemory(g_c_lpszCAPemCert);
|
||||
X509_STORE* store = SSL_CTX_get_cert_store(g_ssl_ctx);
|
||||
X509_STORE_add_cert(store, ca_cert);
|
||||
|
||||
// 加载客户端证书和私钥
|
||||
SSL_CTX_use_certificate(...);
|
||||
SSL_CTX_use_PrivateKey(...);
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 连接到服务器
|
||||
```cpp
|
||||
bool ConnectToServer()
|
||||
{
|
||||
// 创建TCP socket
|
||||
g_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
// 连接到服务器
|
||||
sockaddr_in serverAddr;
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_port = htons(DEFAULT_PORT);
|
||||
inet_pton(AF_INET, DEFAULT_ADDRESS, &serverAddr.sin_addr);
|
||||
connect(g_socket, (sockaddr*)&serverAddr, sizeof(serverAddr));
|
||||
|
||||
// 创建SSL对象并绑定socket
|
||||
g_ssl = SSL_new(g_ssl_ctx);
|
||||
SSL_set_fd(g_ssl, (int)g_socket);
|
||||
|
||||
// 执行SSL握手
|
||||
SSL_connect(g_ssl);
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 发送和接收数据
|
||||
```cpp
|
||||
// 发送
|
||||
bool SendData(const std::string& data)
|
||||
{
|
||||
int sent = SSL_write(g_ssl, data.c_str(), data.length());
|
||||
return sent > 0;
|
||||
}
|
||||
|
||||
// 接收
|
||||
void ReceiveData()
|
||||
{
|
||||
char buffer[1024];
|
||||
int received = SSL_read(g_ssl, buffer, sizeof(buffer) - 1);
|
||||
if (received > 0) {
|
||||
buffer[received] = '\0';
|
||||
// 处理接收到的数据
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 编译
|
||||
```powershell
|
||||
cd "E:\开发\C_C++\hp-socket-6.0.4\hp-socket-6.0.7-src\Windows\Demo\TestEcho-SSL-Console"
|
||||
& "D:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Client-Native\Client-Native.vcxproj /p:Configuration=Debug /p:Platform=x64
|
||||
```
|
||||
|
||||
### 运行
|
||||
1. 先启动Server:
|
||||
```
|
||||
Windows\Demo\Debug\x64\TestEcho-SSL-Console-Server.exe
|
||||
```
|
||||
|
||||
2. 再启动Client-Native:
|
||||
```
|
||||
Windows\Demo\Debug\x64\TestEcho-SSL-Console-Client-Native.exe
|
||||
```
|
||||
|
||||
3. 在Client-Native中按 `1` 发送"hello",服务器会回复"hello!"
|
||||
|
||||
### 命令
|
||||
- `1` - 发送 "hello" 到服务器
|
||||
- `q` - 退出程序
|
||||
|
||||
## 技术要点
|
||||
|
||||
### 1. OpenSSL API使用
|
||||
|
||||
#### 证书加载(从内存)
|
||||
```cpp
|
||||
X509* LoadCertFromMemory(const char* certPem)
|
||||
{
|
||||
BIO* bio = BIO_new_mem_buf(certPem, -1);
|
||||
X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
|
||||
BIO_free(bio);
|
||||
return cert;
|
||||
}
|
||||
```
|
||||
|
||||
#### 私钥加载(带密码)
|
||||
```cpp
|
||||
EVP_PKEY* LoadKeyFromMemory(const char* keyPem, const char* password)
|
||||
{
|
||||
BIO* bio = BIO_new_mem_buf(keyPem, -1);
|
||||
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, (void*)password);
|
||||
BIO_free(bio);
|
||||
return pkey;
|
||||
}
|
||||
```
|
||||
|
||||
#### SSL握手
|
||||
```cpp
|
||||
SSL_connect(g_ssl); // 阻塞调用,直到握手完成
|
||||
```
|
||||
|
||||
### 2. 非阻塞I/O
|
||||
|
||||
为了不阻塞主循环,接收数据使用非阻塞模式:
|
||||
```cpp
|
||||
// 设置为非阻塞
|
||||
u_long mode = 1;
|
||||
ioctlsocket(g_socket, FIONBIO, &mode);
|
||||
|
||||
// 尝试读取(不会阻塞)
|
||||
int received = SSL_read(g_ssl, buffer, size);
|
||||
|
||||
// 恢复阻塞模式
|
||||
mode = 0;
|
||||
ioctlsocket(g_socket, FIONBIO, &mode);
|
||||
```
|
||||
|
||||
### 3. 错误处理
|
||||
|
||||
OpenSSL的错误处理:
|
||||
```cpp
|
||||
void PrintSSLError(const char* msg)
|
||||
{
|
||||
unsigned long err = ERR_get_error();
|
||||
char errBuf[256];
|
||||
ERR_error_string_n(err, errBuf, sizeof(errBuf));
|
||||
std::cout << "[错误] " << msg << ": " << errBuf << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 资源管理
|
||||
|
||||
必须按顺序清理资源:
|
||||
```cpp
|
||||
void Cleanup()
|
||||
{
|
||||
if (g_ssl) {
|
||||
SSL_shutdown(g_ssl); // 关闭SSL连接
|
||||
SSL_free(g_ssl); // 释放SSL对象
|
||||
}
|
||||
|
||||
if (g_socket != INVALID_SOCKET) {
|
||||
closesocket(g_socket); // 关闭socket
|
||||
}
|
||||
|
||||
if (g_ssl_ctx) {
|
||||
SSL_CTX_free(g_ssl_ctx); // 释放SSL上下文
|
||||
}
|
||||
|
||||
WSACleanup(); // 清理Winsock
|
||||
}
|
||||
```
|
||||
|
||||
## 依赖项
|
||||
|
||||
### 头文件
|
||||
- `<winsock2.h>` - Windows Socket API
|
||||
- `<openssl/ssl.h>` - SSL/TLS功能
|
||||
- `<openssl/err.h>` - 错误处理
|
||||
- `<openssl/x509.h>` - X.509证书
|
||||
- `<openssl/bio.h>` - BIO抽象
|
||||
- `<openssl/pem.h>` - PEM格式
|
||||
|
||||
### 库文件
|
||||
- `ws2_32.lib` - Winsock库
|
||||
- `libssl.lib` - OpenSSL SSL库
|
||||
- `libcrypto.lib` - OpenSSL加密库
|
||||
- `crypt32.lib` - Windows加密API库
|
||||
|
||||
### 路径配置
|
||||
```
|
||||
Include: E:\开发\C_C++\hp-socket-6.0.4\hp-socket-6.0.7-src\Windows\Dependent\openssl\14x\x64\include
|
||||
Library: E:\开发\C_C++\hp-socket-6.0.4\hp-socket-6.0.7-src\Windows\Dependent\openssl\14x\x64\lib
|
||||
```
|
||||
|
||||
## 学习价值
|
||||
|
||||
### 对比学习
|
||||
|
||||
通过Client-Native项目,你可以学到:
|
||||
|
||||
1. **底层实现细节**
|
||||
- Socket编程
|
||||
- SSL/TLS握手过程
|
||||
- 证书加载和验证
|
||||
- 加密数据传输
|
||||
|
||||
2. **HP-Socket的价值**
|
||||
- 封装了复杂的底层细节
|
||||
- 提供简洁的API
|
||||
- 自动处理错误和资源管理
|
||||
- 跨平台支持
|
||||
|
||||
3. **SSL/TLS协议理解**
|
||||
- 握手过程
|
||||
- 证书链验证
|
||||
- 密钥交换
|
||||
- 数据加密/解密
|
||||
|
||||
### 代码行数对比
|
||||
|
||||
| 项目 | 代码行数 | 复杂度 |
|
||||
|------|----------|--------|
|
||||
| Client(HP-Socket) | ~273行 | 低 |
|
||||
| Client-Native(原生) | ~450行+ | 中高 |
|
||||
|
||||
**结论:使用HP-Socket可以减少40%+的代码量!**
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 为什么要创建这个项目?
|
||||
A: 为了学习SSL底层实现,理解HP-Socket的封装价值。
|
||||
|
||||
### Q: 实际项目应该用哪个?
|
||||
A: 实际项目强烈推荐使用HP-Socket!Client-Native仅用于学习。
|
||||
|
||||
### Q: Client-Native的性能如何?
|
||||
A: 性能与HP-Socket相当(底层都是OpenSSL),但HP-Socket提供了更多优化和错误处理。
|
||||
|
||||
### Q: 可以用Client-Native连接生产环境吗?
|
||||
A: 不建议。生产环境应使用成熟的库(如HP-Socket),而不是自己实现。
|
||||
|
||||
### Q: 如何添加更多功能?
|
||||
A: 参考HP-Socket的实现,逐步添加:
|
||||
- 异步I/O
|
||||
- 连接池
|
||||
- 断线重连
|
||||
- 心跳检测
|
||||
- 数据缓冲
|
||||
|
||||
## 总结
|
||||
|
||||
**Client-Native项目是一个很好的学习工具**,它帮助你理解:
|
||||
- SSL/TLS通信的底层实现
|
||||
- HP-Socket封装的价值
|
||||
- 网络编程的复杂性
|
||||
|
||||
但对于**实际项目**,请使用HP-Socket或其他成熟的网络库!
|
||||
|
||||
---
|
||||
**创建日期:** 2026年1月13日
|
||||
**作者:** AI Assistant
|
||||
**用途:** 学习和对比
|
||||
**状态:** 完成并可运行
|
||||
Reference in New Issue
Block a user