在C語言中,使用socket進行SSL/TLS加密通信需要使用第三方庫,如OpenSSL。下面是一個簡單的示例,展示了如何使用OpenSSL庫創建一個SSL/TLS客戶端和服務器。
首先,確保已經安裝了OpenSSL庫。在大多數Linux發行版中,可以使用包管理器安裝,例如:
sudo apt-get install libssl-dev
創建一個SSL/TLS服務器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define PORT 8443
#define BUFFER_SIZE 1024
int main() {
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t addr_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
// 初始化SSL上下文
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
ctx = SSL_CTX_new(TLSv1_2_client_method());
if (!ctx) {
fprintf(stderr, "Failed to create SSL context\n");
return 1;
}
// 創建socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("socket");
return 1;
}
// 配置服務器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
// 綁定并監聽socket
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind");
return 1;
}
if (listen(server_fd, 5) < 0) {
perror("listen");
return 1;
}
printf("Server listening on port %d\n", PORT);
// 接受客戶端連接
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addr_len);
if (client_fd < 0) {
perror("accept");
return 1;
}
// 創建SSL對象
ssl = SSL_new(ctx);
if (!ssl) {
fprintf(stderr, "Failed to create SSL object\n");
return 1;
}
// 綁定socket到SSL對象
SSL_set_fd(ssl, client_fd);
// 建立SSL連接
if (SSL_accept(ssl) <= 0) {
fprintf(stderr, "Failed to establish SSL connection\n");
return 1;
}
// 讀取并打印客戶端發送的數據
while (1) {
int len = SSL_read(ssl, buffer, BUFFER_SIZE);
if (len > 0) {
printf("Received from client: %s\n", buffer);
} else if (len == 0) {
break;
} else {
perror("SSL_read");
break;
}
}
// 清理資源
SSL_free(ssl);
SSL_CTX_free(ctx);
close(client_fd);
close(server_fd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define PORT 8443
#define BUFFER_SIZE 1024
int main() {
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
int client_fd;
struct sockaddr_in server_addr;
char buffer[BUFFER_SIZE];
// 初始化SSL上下文
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
ctx = SSL_CTX_new(TLSv1_2_client_method());
if (!ctx) {
fprintf(stderr, "Failed to create SSL context\n");
return 1;
}
// 創建socket
client_fd = socket(AF_INET, SOCK_STREAM, 0);
if (client_fd < 0) {
perror("socket");
return 1;
}
// 配置服務器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(PORT);
// 連接到服務器
if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect");
return 1;
}
// 創建SSL對象
ssl = SSL_new(ctx);
if (!ssl) {
fprintf(stderr, "Failed to create SSL object\n");
return 1;
}
// 綁定socket到SSL對象
SSL_set_fd(ssl, client_fd);
// 建立SSL連接
if (SSL_connect(ssl) <= 0) {
fprintf(stderr, "Failed to establish SSL connection\n");
return 1;
}
// 向服務器發送數據
const char *message = "Hello, server!";
SSL_write(ssl, message, strlen(message));
// 讀取并打印服務器發送的數據
while (1) {
int len = SSL_read(ssl, buffer, BUFFER_SIZE);
if (len > 0) {
printf("Received from server: %s\n", buffer);
} else if (len == 0) {
break;
} else {
perror("SSL_read");
break;
}
}
// 清理資源
SSL_free(ssl);
SSL_CTX_free(ctx);
close(client_fd);
return 0;
}
對于服務器:
gcc server.c -o server -lssl -lcrypto
./server
對于客戶端:
gcc client.c -o client -lssl -lcrypto
./client
現在,服務器和客戶端應該通過SSL/TLS加密進行通信。請注意,這個示例僅用于演示目的,實際應用中可能需要更多的錯誤處理和功能。