openssl创建tls服务端
目录
openssl创建tls服务端
废话不说上代码。
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")
extern "C"
{
#include <openssl/applink.c>
};
// 初始化 OpenSSL
void init_openssl() {
SSL_library_init(); // <<< To clarify my initialization
OpenSSL_add_all_algorithms(); // <<< To clarify my initialization
SSL_load_error_strings(); // <<< To clarify my initialization
ERR_load_crypto_strings(); // <<< To clarify my initialization (2)
OpenSSL_add_all_ciphers();
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
OpenSSL_add_all_ciphers();
}
// 清理 OpenSSL
void cleanup_openssl() {
EVP_cleanup();
}
// 创建 SSL 上下文
SSL_CTX* create_context() {
const SSL_METHOD* method = TLSv1_2_server_method();//SSLv23_server_method();
SSL_CTX* ctx = SSL_CTX_new(method);
if (!ctx) {
std::cerr << "Unable to create SSL context" << std::endl;
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
return ctx;
}
// 配置 SSL 上下文
void configure_context(SSL_CTX* ctx) {
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
int ret = SSL_CTX_load_verify_locations(ctx, "d:\\demo_tls_cert.pem", 0);
if (ret != 1)
{
return ;
}
SSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)"");
// 加载证书和私钥
if (SSL_CTX_use_certificate_file(ctx, "d:\\demo_tls_cert.pem", SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
if (SSL_CTX_use_PrivateKey_file(ctx, "d:\\demo_tls_key.pem", SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
ret = SSL_CTX_check_private_key(ctx);
}
int main() {
// 初始化 Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed" << std::endl;
return 1;
}
// 初始化 OpenSSL
init_openssl();
// 创建 SSL 上下文
SSL_CTX* ctx = create_context();
SSL_CTX_set_security_level(ctx, 0);
configure_context(ctx);
// 创建套接字
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
std::cerr << "Socket creation failed" << std::endl;
return 1;
}
// 绑定套接字
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("172.24.10.116");
server_addr.sin_port = htons(443); // 使用 4433 端口
if (bind(sock, (sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
std::cerr << "Bind failed" << std::endl;
closesocket(sock);
return 1;
}
// 监听连接
if (listen(sock, 16) == SOCKET_ERROR) {
std::cerr << "Listen failed" << std::endl;
closesocket(sock);
return 1;
}
std::cout << "Server listening on port 443..." << std::endl;
// 接受客户端连接
sockaddr_in client_addr;
int client_len = sizeof(client_addr);
SOCKET client_sock = accept(sock, (sockaddr*)&client_addr, &client_len);
if (client_sock == INVALID_SOCKET) {
std::cerr << "Accept failed" << std::endl;
closesocket(sock);
return 1;
}
std::cout << "Client connected" << std::endl;
// 创建 SSL 对象
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_sock);
// 执行 TLS/SSL 握手
if (SSL_accept(ssl) <= 0) {
std::cerr << "SSL handshake failed" << std::endl;
ERR_print_errors_fp(stderr);
}
else {
std::cout << "SSL handshake successful" << std::endl;
// 与客户端通信
char buf[1024];
int bytes = SSL_read(ssl, buf, sizeof(buf));
if (bytes > 0) {
buf[bytes] = '\0';
std::cout << "Received: " << buf << std::endl;
// 发送响应
const char* response = "Hello from server!";
SSL_write(ssl, response, strlen(response));
}
}
// 清理
SSL_shutdown(ssl);
SSL_free(ssl);
closesocket(client_sock);
closesocket(sock);
SSL_CTX_free(ctx);
cleanup_openssl();
WSACleanup();
return 0;
}