《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/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

发表回复

登录后才能评论