C语言实现HTTPS服务器
一、
在当今互联网时代,HTTPS(超文本传输安全协议)已经成为保护网络通信的重要手段,通过加密数据传输,HTTPS能够有效防止数据被窃取和篡改,本文将详细介绍如何使用C语言结合OpenSSL库来实现一个基本的HTTPS服务器。
二、环境准备
1、安装OpenSSL开发包:
在Ubuntu系统上,可以使用以下命令安装OpenSSL开发包:
sudo apt install openssl libssl-dev
在CentOS系统上,可以使用以下命令:
sudo yum install openssl-devel
2、生成自签名证书:
使用OpenSSL命令行工具生成服务器私钥和自签名证书:
openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
三、代码实现
以下是一个简单的C语言实现的HTTPS服务器示例代码:
#include <stdio.h> #include <unistd.h> #include <string.h> #include <signal.h> #include <sys/socket.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> #define BufSize 30 * 1024 #define ServerPort 5555 int create_socket_listen(int port) { int s; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror("Unable to create socket"); exit(EXIT_FAILURE); } if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("Unable to bind"); exit(EXIT_FAILURE); } if (listen(s, 1) < 0) { perror("Unable to listen"); exit(EXIT_FAILURE); } return s; } SSL_CTX* initSSL(const char* cert, const char* key) { SSL_CTX* ctx; SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); ctx = SSL_CTX_new(TLSserver_method()); if (ctx == NULL) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } if (!SSL_CTX_check_private_key(ctx)) { fprintf(stderr, "Private key does not match the public certificate "); exit(EXIT_FAILURE); } return ctx; } int main() { int sock; SSL_CTX* ctx; char buf[BufSize]; signal(SIGPIPE, SIG_IGN); ctx = initSSL("server.crt", "server.key"); sock = create_socket_listen(ServerPort); while (1) { struct sockaddr_in addr; unsigned int len = sizeof(addr); SSL* ssl; const char reply[] = "HTTP/1.1 200 OK\r Date: Fri, 22 May 2009 06:07:21 GMT\r Content-Type: text/html; charset=UTF-8\r \r <html><head></head><body>hello world</body></html>"; int client = accept(sock, (struct sockaddr*)&addr, &len); if (client < 0) { perror("Unable to accept"); exit(EXIT_FAILURE); } ssl = SSL_new(ctx); SSL_set_fd(ssl, client); if (SSL_accept(ssl) <= 0) { ERR_print_errors_fp(stderr); continue; } int size = SSL_read(ssl, buf, BufSize); if (size > 0) { printf("ssl_read: %d bytes ", size); printf("Received message: %s ", buf); } else { ERR_print_errors_fp(stderr); } SSL_write(ssl, reply, strlen(reply)); SSL_shutdown(ssl); SSL_free(ssl); close(client); } close(sock); SSL_CTX_free(ctx); return 0; }
四、代码解析
1、创建监听套接字:create_socket_listen
函数用于创建一个TCP套接字并绑定到指定端口,开始监听连接。
2、初始化SSL上下文:initSSL
函数加载SSL算法,创建SSL上下文并将服务器证书和私钥加载到上下文中。
3、主循环处理客户端连接:在主循环中,服务器接受客户端连接,使用SSL包装TCP连接,读取客户端请求并发送响应。
4、错误处理:使用OpenSSL的错误处理机制打印错误信息。
五、编译和运行
1、编译代码:
gcc https_server.c -lssl -lcrypto -o https_server
2、运行服务器:
./https_server
3、测试服务器:可以使用浏览器或命令行工具(如curl)访问https://your_server_ip:5555
。
六、常见问题解答(FAQs)
Q1: 如何生成自签名证书?
A1: 使用OpenSSL命令行工具生成自签名证书,首先生成私钥文件,然后生成证书签名请求(CSR),最后使用私钥自签名生成证书,具体命令如下:
openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Q2: 如何在不同平台上编译和运行该HTTPS服务器?
A2: 在不同平台上编译和运行该HTTPS服务器需要确保安装了OpenSSL开发包,并使用相应的编译器和链接器选项,在Windows平台上,可以使用MinGW编译器,并确保将OpenSSL库路径添加到环境变量中,编译命令如下:
gcc https_server.c -lssl -lcrypto -o https_server.exe
运行命令:
./https_server.exe
七、小编有话说
实现一个基本的C语言HTTPS服务器不仅有助于理解网络编程和加密通信的基本原理,还能为更复杂的应用打下坚实的基础,通过结合OpenSSL库,开发者可以轻松地为应用添加安全的HTTPS支持,希望本文能为您的学习和开发提供帮助,祝您编码愉快!
原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1484507.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复