OpenSSL实现SSL网络通信

Certainly! Here are the C language programs for a simple OpenSSL client and server that can establish a secure communication channel between them:

l

inux环境下

OpenSSL Server Program (server.c):

c 复制代码
#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 CERT_FILE "server.pem"
#define KEY_FILE "server.key"

void init_openssl() {
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
}

SSL_CTX* create_context() {
    const SSL_METHOD *method;
    SSL_CTX *ctx;

    method = SSLv23_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);

    if (SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    if (SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }
}

int main() {
    int sockfd, clientfd;
    struct sockaddr_in serv_addr, client_addr;
    socklen_t client_len;
    SSL_CTX *ctx;
    SSL *ssl;

    init_openssl();
    ctx = create_context();

    configure_context(ctx);

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Unable to create socket");
        exit(EXIT_FAILURE);
    }

    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(8888);

    if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Unable to bind socket");
        exit(EXIT_FAILURE);
    }

    if (listen(sockfd, 5) < 0) {
        perror("Unable to listen");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port 8888...\n");

    while (1) {
        client_len = sizeof(client_addr);
        clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
        if (clientfd < 0) {
            perror("Unable to accept connection");
            exit(EXIT_FAILURE);
        }

        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, clientfd);

        if (SSL_accept(ssl) <= 0) {
            ERR_print_errors_fp(stderr);
        } else {
            printf("SSL connection established\n");

            char buffer[1024];
            memset(buffer, 0, sizeof(buffer));
            SSL_read(ssl, buffer, sizeof(buffer));
            printf("Received: %s\n", buffer);

            char *response = "Hello from server";
            SSL_write(ssl, response, strlen(response));
            printf("Response sent\n");

            SSL_shutdown(ssl);
            SSL_free(ssl);
        }

        close(clientfd);
    }

    close(sockfd);
    SSL_CTX_free(ctx);
    cleanup_openssl();

    return 0;
}

OpenSSL Client Program (client.c):

c 复制代码
#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 SERVER_IP "127.0.0.1"
#define SERVER_PORT 8888

void init_openssl() {
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
}

SSL_CTX* create_context() {
    const SSL_METHOD *method;
    SSL_CTX *ctx;

    method = SSLv23_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;
}

void configure_context(SSL_CTX *ctx) {
    SSL_CTX_set_default_verify_paths(ctx);
}

int main() {
    int sockfd;
    struct sockaddr_in serv_addr;
    SSL_CTX *ctx;
    SSL *ssl;

    init_openssl();
    ctx = create_context();

    configure_context(ctx);

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Unable to create socket");
        exit(EXIT_FAILURE);
    }

    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERVER_PORTApologies for the abrupt cutoff in the code. Here's the continuation of the OpenSSL client program (client.c):

```c
    if (inet_pton(AF_INET, SERVER_IP, &(serv_addr.sin_addr)) <= 0) {
        perror("Unable to convert server IP address");
        exit(EXIT_FAILURE);
    }

    if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Unable to connect to server");
        exit(EXIT_FAILURE);
    }

    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, sockfd);

    if (SSL_connect(ssl) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    printf("SSL connection established\n");

    char *message = "Hello from client";
    SSL_write(ssl, message, strlen(message));
    printf("Message sent\n");

    char buffer[1024];
    memset(buffer, 0, sizeof(buffer));
    SSL_read(ssl, buffer, sizeof(buffer));
    printf("Received: %s\n", buffer);

    SSL_shutdown(ssl);
    SSL_free(ssl);
    close(sockfd);
    SSL_CTX_free(ctx);
    cleanup_openssl();

    return 0;
}

To compile and run the programs, you'll need to make sure you have the OpenSSL library installed on your system. Use the following command to compile the server and client programs:

bash 复制代码
gcc -o server server.c -lssl -lcrypto
gcc -o client client.c -lssl -lcrypto

Once compiled, you can run the server and client programs separately in different terminal windows. First, start the server:

bash 复制代码
./server

Then, in another terminal window, run the client:

bash 复制代码
./client

You should see the client and server establish an SSL connection and exchange messages securely.

Please let me know if you need any further explanation or examples. If you're ready, we can proceed to the next section: "SSL Certificates and Keys."

相关推荐
上海云盾安全满满4 小时前
高防 IP 是如何帮助数藏行业防刷
网络·网络协议·tcp/ip
吠品5 小时前
免费SSL证书自动化申请:DNS代理验证
网络协议·自动化·ssl
多多*9 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
p***43489 小时前
Rust网络编程模型
开发语言·网络·rust
NewCarRen9 小时前
汽车网络安全管理系统的需求分析及潜在框架设计
网络·汽车网络安全
捷米研发三部9 小时前
CC-Link转Modbus TCP协议转换网关实现三菱 PLC与传感器通讯在快递分拣中心的应用案例
网络·网络协议
嵌入式-小王9 小时前
每天掌握一个网络协议----ARP协议
网络·网络协议·arp
阿珊和她的猫11 小时前
HTTP 状态码 301 和 302 的区别与使用场景
网络·网络协议·http
深度学习040712 小时前
【网络实验】-VLAN工作原理
网络
会飞的土拨鼠呀13 小时前
通过Linux进程id找到程序路径
linux·服务器·网络