OpenSSL是一個強大的加密庫,它提供了許多用于網絡編程的API
在大多數Linux發行版中,OpenSSL庫已經預裝。如果沒有,可以使用包管理器安裝。例如,在基于Debian的系統上,可以使用以下命令安裝:
sudo apt-get install libssl-dev
以下是一個使用OpenSSL庫創建的簡單TCP服務器和客戶端的示例。首先,我們需要創建一個名為server.c
的文件,其中包含以下代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define PORT 8080
void init_openssl() {
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
}
void cleanup_openssl() {
EVP_cleanup();
}
SSL_CTX *create_context() {
const SSL_METHOD *method;
SSL_CTX *ctx;
method = TLS_server_method();
ctx = SSL_CTX_new(method);
if (!ctx) {
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
return ctx;
}
void configure_context(SSL_CTX *ctx) {
SSL_CTX_set_ecdh_auto(ctx, 1);
// Set the key and cert
if (SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
if (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0 ) {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in addr;
SSL_CTX *ctx;
init_openssl();
ctx = create_context();
configure_context(ctx);
sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sock, (struct sockaddr *)&addr, sizeof(addr));
listen(sock, 1);
while (1) {
int client = accept(sock, NULL, NULL);
SSL *ssl;
char reply[] = "Hello, SSL!\n";
ssl = SSL_new(ctx);
SSL_set_fd(ssl, client);
if (SSL_accept(ssl) <= 0) {
ERR_print_errors_fp(stderr);
} else {
SSL_write(ssl, reply, strlen(reply));
}
SSL_shutdown(ssl);
SSL_free(ssl);
close(client);
}
close(sock);
SSL_CTX_free(ctx);
cleanup_openssl();
return 0;
}
接下來,創建一個名為client.c
的文件,其中包含以下代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define PORT 8080
void init_openssl() {
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
}
void cleanup_openssl() {
EVP_cleanup();
}
SSL_CTX *create_context() {
const SSL_METHOD *method;
SSL_CTX *ctx;
method = TLS_client_method();
ctx = SSL_CTX_new(method);
if (!ctx) {
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
return ctx;
}
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in addr;
SSL_CTX *ctx;
SSL *ssl;
char buf[1024];
int bytes;
init_openssl();
ctx = create_context();
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sock, (struct sockaddr *)&addr, sizeof(addr));
if (SSL_connect(ssl) == -1) {
ERR_print_errors_fp(stderr);
} else {
bytes = SSL_read(ssl, buf, sizeof(buf));
buf[bytes] = 0;
printf("Received: %s\n", buf);
}
SSL_shutdown(ssl);
SSL_free(ssl);
close(sock);
SSL_CTX_free(ctx);
cleanup_openssl();
return 0;
}
使用以下命令編譯服務器和客戶端:
gcc server.c -o server -lssl -lcrypto
gcc client.c -o client -lssl -lcrypto
首先,運行服務器:
./server
然后,在另一個終端中運行客戶端:
./client
客戶端將連接到服務器并接收一條加密消息:“Hello, SSL!”。
這只是一個簡單的示例,OpenSSL庫提供了許多其他功能,如加密、解密、簽名和驗證。你可以根據自己的需求使用這些功能。