备份-基础ssl通信

This commit is contained in:
睿 安
2026-01-23 08:39:07 +08:00
parent ef6b8511b1
commit dbb053a691
625 changed files with 305003 additions and 0 deletions

View File

@@ -0,0 +1,257 @@
#include "pch.h"
#include "SSLClientConnection.h"
namespace SSLClient {
SSLClientConnection::SSLClientConnection()
: m_sslContext(nullptr)
, m_ssl(nullptr)
, m_socket(INVALID_SOCKET)
, m_isConnected(false)
{
}
SSLClientConnection::~SSLClientConnection()
{
Cleanup();
}
bool SSLClientConnection::InitializeWinsock()
{
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0) {
std::cerr << "[错误] WSAStartup失败错误码: " << result << std::endl;
return false;
}
return true;
}
bool SSLClientConnection::Initialize(const char* clientCert, const char* clientKey,
const char* caCert, const char* keyPassword)
{
// 初始化Winsock
if (!InitializeWinsock()) {
return false;
}
std::cout << "[客户端] 正在初始化SSL环境..." << std::endl;
// 创建SSL上下文
m_sslContext = SSL_CTX_new(TLS_client_method());
if (!m_sslContext) {
CertificateManager::PrintSSLError("创建SSL上下文失败");
return false;
}
// 设置验证模式:验证服务器证书
SSL_CTX_set_verify(m_sslContext, SSL_VERIFY_PEER, nullptr);
// 加载CA证书
X509* ca = m_certManager.LoadCertificateFromMemory(caCert);
if (!ca) {
return false;
}
X509_STORE* store = SSL_CTX_get_cert_store(m_sslContext);
if (X509_STORE_add_cert(store, ca) != 1) {
CertificateManager::PrintSSLError("添加CA证书失败");
X509_free(ca);
return false;
}
X509_free(ca);
// 加载客户端证书
X509* cert = m_certManager.LoadCertificateFromMemory(clientCert);
if (!cert) {
return false;
}
if (SSL_CTX_use_certificate(m_sslContext, cert) != 1) {
CertificateManager::PrintSSLError("使用客户端证书失败");
X509_free(cert);
return false;
}
X509_free(cert);
// 加载客户端私钥
EVP_PKEY* pkey = m_certManager.LoadPrivateKeyFromMemory(clientKey, keyPassword);
if (!pkey) {
return false;
}
if (SSL_CTX_use_PrivateKey(m_sslContext, pkey) != 1) {
CertificateManager::PrintSSLError("使用客户端私钥失败");
EVP_PKEY_free(pkey);
return false;
}
EVP_PKEY_free(pkey);
// 验证私钥和证书是否匹配
if (SSL_CTX_check_private_key(m_sslContext) != 1) {
std::cerr << "[错误] 客户端私钥和证书不匹配" << std::endl;
return false;
}
std::cout << "[客户端] SSL环境初始化成功" << std::endl;
return true;
}
bool SSLClientConnection::Connect(const char* address, int port)
{
// 创建socket
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET) {
std::cerr << "[错误] 创建socket失败错误码: " << WSAGetLastError() << std::endl;
return false;
}
// 设置服务器地址
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(static_cast<u_short>(port));
inet_pton(AF_INET, address, &serverAddr.sin_addr);
// 连接到服务器
std::cout << "[客户端] 正在连接服务器 " << address << ":" << port << " ..." << std::endl;
if (connect(m_socket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cerr << "[错误] 连接失败,错误码: " << WSAGetLastError() << std::endl;
closesocket(m_socket);
m_socket = INVALID_SOCKET;
return false;
}
std::cout << "[客户端] TCP连接成功" << std::endl;
// 创建SSL对象
m_ssl = SSL_new(m_sslContext);
if (!m_ssl) {
CertificateManager::PrintSSLError("创建SSL对象失败");
closesocket(m_socket);
m_socket = INVALID_SOCKET;
return false;
}
// 将SSL绑定到socket
if (SSL_set_fd(m_ssl, static_cast<int>(m_socket)) != 1) {
CertificateManager::PrintSSLError("绑定SSL到socket失败");
SSL_free(m_ssl);
m_ssl = nullptr;
closesocket(m_socket);
m_socket = INVALID_SOCKET;
return false;
}
// 执行SSL握手
std::cout << "[客户端] 正在进行SSL握手..." << std::endl;
int ret = SSL_connect(m_ssl);
if (ret != 1) {
int err = SSL_get_error(m_ssl, ret);
std::cerr << "[错误] SSL握手失败错误码: " << err << std::endl;
CertificateManager::PrintSSLError("SSL_connect");
SSL_free(m_ssl);
m_ssl = nullptr;
closesocket(m_socket);
m_socket = INVALID_SOCKET;
return false;
}
m_isConnected = true;
std::cout << "[客户端] SSL握手完成" << std::endl;
std::cout << "[客户端] 使用的加密套件: " << GetCipherSuite() << std::endl;
return true;
}
bool SSLClientConnection::Send(const std::string& data)
{
if (!m_isConnected || !m_ssl) {
std::cerr << "[错误] 未连接到服务器" << std::endl;
return false;
}
int sent = SSL_write(m_ssl, data.c_str(), static_cast<int>(data.length()));
if (sent <= 0) {
int err = SSL_get_error(m_ssl, sent);
std::cerr << "[错误] 发送失败,错误码: " << err << std::endl;
CertificateManager::PrintSSLError("SSL_write");
return false;
}
std::cout << "[客户端] 发送数据: \"" << data << "\" (" << sent << " 字节)" << std::endl;
return true;
}
int SSLClientConnection::Receive(char* buffer, int bufferSize)
{
if (!m_isConnected || !m_ssl || !buffer || bufferSize <= 0) {
return -1;
}
// 设置socket为非阻塞模式
u_long mode = 1;
ioctlsocket(m_socket, FIONBIO, &mode);
int received = SSL_read(m_ssl, buffer, bufferSize - 1);
// 恢复为阻塞模式
mode = 0;
ioctlsocket(m_socket, FIONBIO, &mode);
if (received > 0) {
buffer[received] = '\0';
std::cout << "[客户端] 收到数据: \"" << buffer << "\" (" << received << " 字节)" << std::endl;
return received;
}
else if (received < 0) {
int err = SSL_get_error(m_ssl, received);
// SSL_ERROR_WANT_READ 和 SSL_ERROR_WANT_WRITE 表示没有数据,不是错误
if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
if (err != SSL_ERROR_ZERO_RETURN) { // 忽略正常关闭
std::cerr << "[错误] 接收失败,错误码: " << err << std::endl;
}
return -1;
}
}
return 0; // 没有数据
}
void SSLClientConnection::Disconnect()
{
std::cout << "[客户端] 正在断开连接..." << std::endl;
Cleanup();
m_isConnected = false;
std::cout << "[客户端] 已断开连接" << std::endl;
}
const char* SSLClientConnection::GetCipherSuite() const
{
if (m_ssl) {
return SSL_get_cipher(m_ssl);
}
return "未知";
}
void SSLClientConnection::Cleanup()
{
if (m_ssl) {
SSL_shutdown(m_ssl);
SSL_free(m_ssl);
m_ssl = nullptr;
}
if (m_socket != INVALID_SOCKET) {
closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
if (m_sslContext) {
SSL_CTX_free(m_sslContext);
m_sslContext = nullptr;
}
WSACleanup();
}
} // namespace SSLClient