《openssl庫全面詳解》

一、openssl庫概述

OpenSSL庫是一個開放源代碼庫,提供了用於SSL / TLS協議的加密,解密和驗證功能,以及用於密碼學的功能。它可以用於安全的網絡通信,數字簽名和證書管理。OpenSSL是一個跨平台的庫,適用於多種操作系統,包括Windows,Linux,Unix等等。

OpenSSL庫提供了兩種主要的API,C語言API和命令行工具API。C語言API包含了700多個函數,其中有很多函數都是用於不同種類加密,解密和簽名算法等等方面。命令行工具API可以讓用戶通過命令行直接操作SSL功能,包括TLS握手、創建和管理密鑰、證書和CRLs等等。

下面介紹一些常用openssl功能及其用法。

二、加密解密

OpenSSL庫提供了多種加密算法,包括對稱加密算法和非對稱加密算法。下面以AES加密算法為例,介紹OpenSSL的加密解密功能。

 //AES加密
int aes_encrypt(unsigned char *in_data, int in_data_len, unsigned char *out_data, unsigned char *key, unsigned char *iv) {
    EVP_CIPHER_CTX *ctx;
    int out_len, len;
    int ret = 0;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new())) return ERR_EVP_CIPHER_INIT;

    /* Initialise the encryption operation. IMPORTANT - ensure you use a key and IV size appropriate for your cipher */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) return ERR_EVP_CIPHER_INIT;

    /* Provide the message to be encrypted, and obtain the encrypted output. EVP_EncryptUpdate can be called multiple times if necessary */
    if(1 != EVP_EncryptUpdate(ctx, out_data, &out_len, in_data, in_data_len)) ret=ERR_EVP_FAILED;
    else {
        /* Finalise the encryption. Further data cannot be encrypted */
        if(1 != EVP_EncryptFinal_ex(ctx, out_data + out_len, &len)) ret=ERR_EVP_FAILED;
        else out_len += len;
    }

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);
    return ret;
}

//AES解密
int aes_decrypt(unsigned char *in_data, int in_data_len, unsigned char *out_data, unsigned char *key, unsigned char *iv) {
    EVP_CIPHER_CTX *ctx;
    int out_len, len;
    int ret = 0;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new())) return ERR_EVP_CIPHER_INIT;

    /* Initialise the decryption operation. IMPORTANT - ensure you use a key and IV size appropriate for your cipher */
    if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) return ERR_EVP_CIPHER_INIT;

    /* Provide the message to be decrypted, and obtain the plaintext output. EVP_DecryptUpdate can be called multiple times if necessary */
    if(1 != EVP_DecryptUpdate(ctx, out_data, &out_len, in_data, in_data_len)) ret = ERR_EVP_FAILED;
    else {
        /* Finalise the decryption. Further data cannot be decrypted */
        if(1 != EVP_DecryptFinal_ex(ctx, out_data + out_len, &len)) ret=ERR_EVP_FAILED;
        else out_len += len;
    }

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);
    return ret;
}

三、密碼學

OpenSSL庫提供了多種密碼學算法,包括哈希算法、消息認證碼算法、數字簽名算法等等。下面以SHA256算法為例,介紹OpenSSL的密碼學功能。

 //SHA256哈希算法
int sha256_hash(unsigned char *data, unsigned int data_len, unsigned char *hash) {
    EVP_MD_CTX *mdctx;

    /* Create and initialise the context */
    if(!(mdctx = EVP_MD_CTX_create())) return ERR_EVP_MD_INIT;

    /* Initialise the message digest operation with the SHA-256 algorithm */
    if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) return ERR_EVP_MD_INIT;

    /* Provide the message to be hashed, and obtain the hashed output */
    if(1 != EVP_DigestUpdate(mdctx, data, data_len)) return ERR_EVP_MD_FAILED;
    if(1 != EVP_DigestFinal_ex(mdctx, hash, NULL)) return ERR_EVP_MD_FAILED;

    /* Clean up */
    EVP_MD_CTX_destroy(mdctx);
    return 0;
}

四、證書管理

OpenSSL庫提供了多種證書管理的功能,包括證書創建、查看和驗證等等。下面以證書查看功能為例,介紹OpenSSL的證書管理功能。

//讀取x509格式證書信息
int read_x509_certificate(const char *cert_file, X509 **x509) {
	FILE *fp = NULL;
    int ret = 0;
    if ((fp = fopen(cert_file, "r")) == NULL) return ERR_X509_FAILED;

    /* Create a new X509 object */
    if ((*x509 = X509_new()) == NULL) return ERR_X509_FAILED;

    /* Read the certificate from the file into the X509 object */
    if(!PEM_read_X509(fp, x509, 0, NULL)) ret = ERR_X509_FAILED;
    fclose(fp);
    return ret;
}

//獲取證書信息
int get_subject_name(X509 *x509, char *subject_name, size_t name_len) {
    X509_NAME *name;
    BIO *outbio = BIO_new(BIO_s_mem());
    if (!outbio) return ERR_BIO_FAILED;

    /* Get the subject name from the X509 object */
    name = X509_get_subject_name(x509);
    X509_NAME_print_ex(outbio, name, 0, XN_FLAG_RFC2253);

    /* Copy the name to the output buffer */
    memset(subject_name, 0, name_len);
    if (BIO_read(outbio, subject_name, name_len-1) <= 0) {
        BIO_free(outbio);
        return ERR_BIO_FAILED;
    }

    BIO_free(outbio);
    return 0;
}

五、TLS/SSL通信

OpenSSL庫最重要的功能之一就是處理SSL/TLS通信,下面以SSL/TLS服務器的創建和客戶端的連接為例,介紹OpenSSL的TLS/SSL通信功能。

//TLS/SSL服務器
int server_start(int listen_fd, SSL_CTX *ctx) {
    int conn_fd;
    socklen_t client_len;
    struct sockaddr_in client_addr;
    SSL *ssl;

    while (1) {
        client_len = sizeof(client_addr);
        /* Wait for a client to connect */
        if ((conn_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_len)) < 0) continue;

        /* Create a new SSL object for the connection */
        if ((ssl = SSL_new(ctx)) == NULL) {
            close(conn_fd);
            continue;
        }

        /* Attach the socket descriptor to the SSL object */
        if (!SSL_set_fd(ssl, conn_fd)) {
            SSL_free(ssl);
            close(conn_fd);
            continue;
        }

        /* Perform the SSL/TLS handshake */
        if (SSL_accept(ssl) ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) continue;

        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            continue;
        }

        break;
    }

    if (p == NULL) return ERR_SOCKET_FAILED;

    /* Create a new SSL object for the connection */
    if ((ssl = SSL_new(ctx)) == NULL) {
        close(sockfd);
        return ERR_SSL_FAILED;
    }

    /* Attach the socket descriptor to the SSL object */
    if (!SSL_set_fd(ssl, sockfd)) {
        SSL_free(ssl);
        close(sockfd);
        return ERR_SSL_FAILED;
    }

    /* Perform the SSL/TLS handshake */
    if (SSL_connect(ssl) <= 0) {
        SSL_free(ssl);
        close(sockfd);
        return ERR_SSL_FAILED;
    }

    /* Handle the server connection */
    handle_server(ssl);

    /* Clean up the SSL object */
    SSL_shutdown(ssl);
    SSL_free(ssl);
    close(sockfd);

    freeaddrinfo(servinfo);
    return 0;
}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/181862.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-23 06:43
下一篇 2024-11-23 06:43

相關推薦

  • Python應用程序的全面指南

    Python是一種功能強大而簡單易學的編程語言,適用於多種應用場景。本篇文章將從多個方面介紹Python如何應用於開發應用程序。 一、Web應用程序 目前,基於Python的Web…

    編程 2025-04-29
  • Python zscore函數全面解析

    本文將介紹什麼是zscore函數,它在數據分析中的作用以及如何使用Python實現zscore函數,為讀者提供全面的指導。 一、zscore函數的概念 zscore函數是一種用於標…

    編程 2025-04-29
  • 全面解讀數據屬性r/w

    數據屬性r/w是指數據屬性的可讀/可寫性,它在程序設計中扮演着非常重要的角色。下面我們從多個方面對數據屬性r/w進行詳細的闡述。 一、r/w的概念 數據屬性r/w即指數據屬性的可讀…

    編程 2025-04-29
  • Python計算機程序代碼全面介紹

    本文將從多個方面對Python計算機程序代碼進行詳細介紹,包括基礎語法、數據類型、控制語句、函數、模塊及面向對象編程等。 一、基礎語法 Python是一種解釋型、面向對象、動態數據…

    編程 2025-04-29
  • Matlab二值圖像全面解析

    本文將全面介紹Matlab二值圖像的相關知識,包括二值圖像的基本原理、如何對二值圖像進行處理、如何從二值圖像中提取信息等等。通過本文的學習,你將能夠掌握Matlab二值圖像的基本操…

    編程 2025-04-28
  • 瘋狂Python講義的全面掌握與實踐

    本文將從多個方面對瘋狂Python講義進行詳細的闡述,幫助讀者全面了解Python編程,掌握瘋狂Python講義的實現方法。 一、Python基礎語法 Python基礎語法是學習P…

    編程 2025-04-28
  • 全面解析Python中的Variable

    Variable是Python中常見的一個概念,是我們在編程中經常用到的一個變量類型。Python是一門強類型語言,即每個變量都有一個對應的類型,不能無限制地進行類型間轉換。在本篇…

    編程 2025-04-28
  • Zookeeper ACL 用戶 anyone 全面解析

    本文將從以下幾個方面對Zookeeper ACL中的用戶anyone進行全面的解析,並為讀者提供相關的示例代碼。 一、anyone 的作用是什麼? 在Zookeeper中,anyo…

    編程 2025-04-28
  • Switchlight的全面解析

    Switchlight是一個高效的輕量級Web框架,為開發者提供了簡單易用的API和豐富的工具,可以快速構建Web應用程序。在本文中,我們將從多個方面闡述Switchlight的特…

    編程 2025-04-28
  • Python合集符號全面解析

    Python是一門非常流行的編程語言,在其語法中有一些特殊的符號被稱作合集符號,這些符號在Python中起到非常重要的作用。本文將從多個方面對Python合集符號進行詳細闡述,幫助…

    編程 2025-04-28

發表回復

登錄後才能評論