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

相关推荐
IPIDEA全球IP代理26 分钟前
跨境卖家该选静态IP还是动态IP?
网络·网络协议·tcp/ip
东风西巷30 分钟前
MyLanViewer(局域网IP扫描软件)
前端·网络·网络协议·tcp/ip·电脑·软件需求
知北游天44 分钟前
Linux网络:使用TCP实现网络通信(服务端)
linux·网络·tcp/ip
熙客1 小时前
阿里云负载均衡SLB的使用
网络·阿里云·云原生·云计算·负载均衡
Guheyunyi1 小时前
用气安全与能效优化平台
运维·网络·人工智能·安全·音视频
思成不止于此1 小时前
软考中级软件设计师备考指南(四):I/O 技术、安全与可靠性 —— 综合应用篇
网络·笔记·学习·信息安全·总线系统·i/o 技术·可靠性计算
羑悻的小杀马特2 小时前
从监听风险到绝对隐私:Zoom偷听门后,Briefing+CPolar重新定义远程会议安全标准
网络·安全·briefing
半桔2 小时前
【网络编程】从数据链路层帧头到代理服务器:解析路由表、MTU/MSS、ARP、NAT 等网络核心技术
linux·运维·服务器·网络
ZLRRLZ4 小时前
【ProtoBuffer】protobuffer的安装与使用
服务器·网络
像素之间7 小时前
HTTP之content-disposition
网络·网络协议·http