• 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):

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    OpenSSL Client Program (client.c):

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    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:

    gcc -o server server.c -lssl -lcrypto
    gcc -o client client.c -lssl -lcrypto
    
    • 1
    • 2

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

    ./server
    
    • 1

    Then, in another terminal window, run the client:

    ./client
    
    • 1

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

  • 相关阅读:
    NAACL 2022 | TAMT:通过下游任务无关掩码训练搜索可迁移的BERT子网络
    K8S常用kubectl命令汇总(持续更新中)
    Java错题归纳day18
    Idea使用技巧——导包优化,新版idea界面取消,界面字体放大缩小
    元数据 对Mysql的借鉴的思考
    bootstrap系列-6.BooStrap表单(上)
    centos7 进行Python3.9 Django3项目迁移启动asgi
    Mysql高级——索引
    手写vue响应式
    系列十二、Redis的主从复制
  • 原文地址:https://blog.csdn.net/m0_53870075/article/details/134159429