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."

相关推荐
M1582276905515 分钟前
TCP转LORA产品说明及应用案例
网络·网络协议·tcp/ip
旖旎夜光19 分钟前
Linux(13)(中)
linux·网络
来可电子CAN青年34 分钟前
CAN总线远距离传输老断网?Fx灯不闪别慌,这几招让你的通信“稳如泰山”!
网络
独行soc34 分钟前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
云小逸38 分钟前
【nmap源码解析】Nmap OS识别核心模块深度解析:osscan2.cc源码剖析(1)
开发语言·网络·学习·nmap
自不量力的A同学1 小时前
Solon AI v3.9 正式发布:全能 Skill 爆发
java·网络·人工智能
ESBK20251 小时前
第四届移动互联网、云计算与信息安全国际会议(MICCIS 2026)二轮征稿启动,诚邀全球学者共赴学术盛宴
大数据·网络·物联网·网络安全·云计算·密码学·信息与通信
莽撞的大地瓜2 小时前
洞察,始于一目了然——让舆情数据自己“说话”
大数据·网络·数据分析
那就回到过去2 小时前
MSTP路由协议简介
网络·网络协议·tcp/ip·ensp
浩浩测试一下2 小时前
内网---> WriteOwner权限滥用
网络·汇编·windows·安全·microsoft·系统安全