OpenSSL 基础使用流程

理解 OpenSSL 的基础使用流程是学习如何进行安全通信的关键,特别是在实现 SSL/TLS 连接时。以下是 OpenSSL 基础使用流程的一个简要总结,并附上一个简单的示例代码,帮助你理解如何通过 OpenSSL 建立一个基本的安全通信连接。

OpenSSL 基础使用流程

  1. 初始化 OpenSSL
    在使用 OpenSSL 之前,你需要先初始化 OpenSSL 库。这个初始化过程会加载加密算法、SSL 库等所需的组件。

  2. 创建 SSL 上下文 (SSL_CTX)
    SSL_CTX 是管理 SSL 连接的上下文对象,类似于一个配置容器,它包含了 SSL 连接所需的所有参数和设置。

  3. 创建 SSL 对象 (SSL)
    SSL 对象表示一个具体的 SSL 连接,它用于与客户端或服务器进行加密通信。

  4. 设置证书和私钥
    对于服务器来说,你需要提供证书和私钥。这些信息用于加密和验证数据传输的安全性。

  5. 建立连接
    在建立 TCP 连接之后,SSL 连接会在这个 TCP 连接的基础上进行握手、加密数据交换等操作。

  6. 进行 SSL/TLS 握手
    握手是建立安全连接的过程,客户端和服务器通过此过程协商加密算法、交换密钥等。

  7. 读写加密数据
    通过 SSL_read()SSL_write() 函数,你可以在加密的 SSL/TLS 连接上进行安全的数据读写。

  8. 关闭连接
    使用完毕后,记得关闭 SSL 连接并释放资源。


示例代码

以下是一个简单的 OpenSSL 客户端和服务器的代码示例,展示了如何使用 OpenSSL 创建一个基本的 SSL/TLS 连接。

1. 客户端代码示例
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define SERVER_PORT 4433
#define SERVER_IP "127.0.0.1"

int main() {
    // 初始化 OpenSSL
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();

    // 创建 SSL 上下文
    SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
    if (!ctx) {
        std::cerr << "Error creating SSL_CTX" << std::endl;
        return -1;
    }

    // 创建 SSL 对象
    SSL *ssl = SSL_new(ctx);

    // 创建 socket 并连接到服务器
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "Error connecting to server" << std::endl;
        return -1;
    }

    // 将 socket 与 SSL 对象关联
    SSL_set_fd(ssl, sock);

    // SSL 握手
    if (SSL_connect(ssl) <= 0) {
        std::cerr << "SSL connect failed" << std::endl;
        return -1;
    }
    std::cout << "SSL Connection established!" << std::endl;

    // 发送数据
    const char *msg = "Hello, secure world!";
    if (SSL_write(ssl, msg, strlen(msg)) <= 0) {
        std::cerr << "Error writing to SSL" << std::endl;
    }

    // 接收数据
    char buffer[1024];
    int bytes = SSL_read(ssl, buffer, sizeof(buffer)-1);
    if (bytes > 0) {
        buffer[bytes] = 0;
        std::cout << "Received: " << buffer << std::endl;
    }

    // 关闭 SSL 连接
    SSL_shutdown(ssl);
    close(sock);

    // 清理资源
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}
2. 服务器代码示例
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>

#define SERVER_PORT 4433

int main() {
    // 初始化 OpenSSL
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();

    // 创建 SSL 上下文
    SSL_CTX *ctx = SSL_CTX_new(TLS_server_method());
    if (!ctx) {
        std::cerr << "Error creating SSL_CTX" << std::endl;
        return -1;
    }

    // 加载证书和私钥
    if (SSL_CTX_use_certificate_file(ctx, "server_cert.pem", SSL_FILETYPE_PEM) <= 0 ||
        SSL_CTX_use_PrivateKey_file(ctx, "server_key.pem", SSL_FILETYPE_PEM) <= 0) {
        std::cerr << "Error loading certificate or private key" << std::endl;
        return -1;
    }

    // 创建 socket 并绑定到指定端口
    int server_sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "Error binding server socket" << std::endl;
        return -1;
    }

    // 监听连接
    if (listen(server_sock, 1) < 0) {
        std::cerr << "Error listening on socket" << std::endl;
        return -1;
    }

    std::cout << "Waiting for a client to connect..." << std::endl;
    int client_sock = accept(server_sock, NULL, NULL);
    if (client_sock < 0) {
        std::cerr << "Error accepting connection" << std::endl;
        return -1;
    }

    // 创建 SSL 对象
    SSL *ssl = SSL_new(ctx);

    // 将 socket 与 SSL 对象关联
    SSL_set_fd(ssl, client_sock);

    // SSL 握手
    if (SSL_accept(ssl) <= 0) {
        std::cerr << "SSL accept failed" << std::endl;
        return -1;
    }
    std::cout << "SSL Connection established!" << std::endl;

    // 接收数据
    char buffer[1024];
    int bytes = SSL_read(ssl, buffer, sizeof(buffer)-1);
    if (bytes > 0) {
        buffer[bytes] = 0;
        std::cout << "Received: " << buffer << std::endl;
    }

    // 发送数据
    const char *msg = "Hello, secure client!";
    if (SSL_write(ssl, msg, strlen(msg)) <= 0) {
        std::cerr << "Error writing to SSL" << std::endl;
    }

    // 关闭 SSL 连接
    SSL_shutdown(ssl);
    close(client_sock);
    close(server_sock);

    // 清理资源
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}

重点概念解析

  1. SSL_CTX(SSL 上下文)
    SSL_CTX 是配置 SSL/TLS 连接所需的所有参数和设置的容器,它在整个连接生命周期中被共享。

  2. SSL 对象
    每个 SSL/TLS 连接都有一个 SSL 对象,它包含了具体的 SSL 连接信息,包括连接的协议版本、加密算法等。

  3. 证书和私钥的加载
    对于 SSL 服务器,必须加载证书和私钥,这些用于加密和解密数据流。

  4. SSL 握手
    握手阶段用于协商加密算法和生成共享密钥,确保客户端和服务器可以安全地交换数据。

  5. 数据的加密和解密
    使用 SSL_write()SSL_read() 对数据进行加密和解密,保证数据的安全性。

  6. 错误处理
    OpenSSL 提供了丰富的错误信息,使用 SSL_get_error()ERR_get_error() 获取错误详细信息,帮助调试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980361.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【基于Raft的KV共识算法】-序:Raft概述

本文目录 1.为什么会有Raft&#xff1f;CAP理论 2.Raft基本原理流程为什么要以日志作为中间载体&#xff1f; 3.实现思路任期领导选举日志同步 1.为什么会有Raft&#xff1f; 简单来说就是数据会随着业务和时间的增长&#xff0c;单机不能存的下&#xff0c;这个时候需要以某种…

Redis---LRU原理与算法实现

文章目录 LRU概念理解LRU原理基于HashMap和双向链表实现LRURedis中的LRU的实现LRU时钟淘汰策略近似LRU的实现LRU算法的优化 Redis LRU的核心代码逻辑Redis LRU的核心代码逻辑Redis LRU的配置参数Redis LRU的优缺点Redis LRU的优缺点 LRU概念理解 LRU&#xff08;Least Recentl…

【Java-黑马程序员】2024IDEA下载安装[ IntelliJ IDEA]

IDEA概述 IntelliJ IDEA – 用于 Pro Java 和 Kotlin 开发的 IDEhttps://www.jetbrains.com/idea/安装:傻瓜式安装,建议修改安装路径。 选择版本 Ultimate:功能全面,适合企业开发,需付费。 Community:免费,适合个人和小型项目。 选择适合你操作系统的版本 Windows版…

centos 下dockers部署surveyking-docker开源考试系统

下载初始化脚本&#xff0c;并自动部署至当前文件夹 https://raw.githubusercontent.com/xianyu-one/surveyking-docker/main/setup.sh -O setup.sh chmod x setup.sh bash setup.sh 手工部署 1:先卸载这些旧版本&#xff0c;以及关联的依赖项sudo yum remove docker docker-…

[3/11]C#性能优化-实现 IDisposable 接口-每个细节都有示例代码

[3]C#性能优化-实现 IDisposable 接口-每个细节都有示例代码 前言 在C#开发中&#xff0c;性能优化是提升系统响应速度和资源利用率的关键环节。 当然&#xff0c;同样是所有程序的关键环节。 通过遵循下述建议&#xff0c;可以有效地减少不必要的对象创建&#xff0c;从而减…

【deepseek第二课】docker部署dify,配置私有化知识库,解决网络超时,成功安装

【deepseek第二课】docker部署dify&#xff0c;配置私有化知识库&#xff0c;解决网络超时&#xff0c;成功安装 1. dify安装1.1 官网安装文档介绍1.2 安装报错&#xff0c;网络连接问题使用镜像加速器处理1.3 dify后台启动很多docker进程 2. 页面探索2.1 设置管理账号2.2 添加…

2025.3.2机器学习笔记:PINN文献阅读

2025.3.2周报 一、文献阅读题目信息摘要Abstract创新点网络架构实验结论不足以及展望 一、文献阅读 题目信息 题目&#xff1a; Physics-Informed Neural Networks of the Saint-Venant Equations for Downscaling a Large-Scale River Model期刊&#xff1a; Water Resource…

在C++中如何实现线程安全的队列

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言如何实现一个线程安全的队列思路应用场景代码实现总结 前言 在一次和豆包的模拟面试中&#xff0c;豆包问我&#xff1a;“在C中&#xf…

【网络安全 | 漏洞挖掘】利用文件上传功能的 IDOR 和 XSS 劫持会话

未经许可,不得转载。 本文涉及漏洞均已修复。 文章目录 前言正文前言 想象这样一个场景:一个专门处理敏感文档的平台,如保险理赔或身份验证系统,却因一个设计疏漏而成为攻击者的“金矿”。在对某个保险门户的文件上传功能进行测试时,我意外发现了一个可导致大规模账户接管…

[操作系统] 文件的软链接和硬链接

文章目录 引言硬链接&#xff08;Hard Link&#xff09;什么是硬链接&#xff1f;硬链接的特性硬链接的用途 软链接&#xff08;Symbolic Link&#xff09;什么是软链接&#xff1f;软链接的特性软链接的用途 软硬链接对比文件的时间戳实际应用示例使用硬链接节省备份空间用软链…

c# winform程序 vs2022 打包生成安装包

最近&#xff0c;利用c# winform程序该客户开发一套进销存管理系统&#xff0c;项目在部署前&#xff0c;需要生成安装包&#xff0c;以便部署在客户电脑上面。总结步骤如下&#xff1a; 1、在打包之前 (VS中需要包括Microsoft visual studio installer projects扩展项目)&…

现今大语言模型性能(准确率)比较

现今大语言模型性能(准确率)比较 表头信息:表的标题为“大语言模型性能比较结果”(英文:Table 1: Large Language Model Performance Comparison Results),表明该表是用于对比不同大语言模型的性能。列信息: 模型:列出参与比较的不同大语言模型名称,包括LLAMA3(70B)…

Mysql-如何理解事务?

一、事务是什么东西 有些场景中&#xff0c;某个操作需要多个sql配合完成&#xff1a; 例如&#xff1a; 李四这个月剩下的前不够交房租了&#xff0c;找张三借1000元急用&#xff1a; &#xff08;1&#xff09;给张三的账户余额 减去1000元 updata 账户表 set money money -…

GitLab Pages 托管静态网站

文章目录 新建项目配置博客添加 .gitlab-ci.yml其他配置 曾经用 Github Pages 来托管博客内容&#xff0c;但是有一些不足&#xff1a; 在不科学上网的情况下&#xff0c;是没法访问的&#xff0c;或者访问速度非常慢代码仓库必须是公开的&#xff0c;如果设置为私有&#xff0…

智能图像处理平台:图片管理

接着我们讲图片管理&#xff0c;先实现图片基础的增删改查&#xff0c;再去考虑图像处理。 主要是&#xff0c;我们需要完成查询时&#xff0c;查询的图片的上传者的角色等级小于等于我们当前登陆账号。 后端controller&#xff1a; package com.llpp.controller;import cn.…

计算机毕业设计Hadoop+Spark+DeepSeek-R1大模型音乐推荐系统 音乐数据分析 音乐可视化 音乐爬虫 知识图谱 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

《Python实战进阶》No 11:微服务架构设计与 Python 实现

第11集&#xff1a;微服务架构设计与 Python 实现 2025年3月3日更新了代码和微服务运行后的系统返回信息截图&#xff0c;所有代码在 python3.11.5虚拟环境下运行通过。 微服务架构通过将复杂应用拆分为独立部署的小型服务&#xff0c;显著提升了系统的可扩展性和维护性。本集…

NC2227_约瑟夫环

题解: import java.util.Scanner;​public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();int k sc.nextInt();int m sc.nextInt();int set 0;for(int i 2;i < n;i ){set (set m) % i;}System.out.p…

openEuler操作系统

一、OpenEuler简介 OpenEuler 是一款由华为发起、社区驱动的开源 Linux 操作系统&#xff0c;专注于企业级应用场景(如服务器、云计算、边缘计算等)。其前身是华为的 EulerOS&#xff0c;2019 年正式开源并捐赠给开放原子开源基金会&#xff0c;旨在构建一个中立、开放的生态系…

vite+react+ts如何集成redux状态管理工具,实现持久化缓存

1.安装插件 这里的redux-persist--进行数据的持久化缓存&#xff0c;确保页面刷新数据不会丢失 yarn add react-redux^9.2.0 redux-persist^6.0.0 reduxjs/toolkit^2.5.1 2.创建仓库文件夹 在项目的src文件夹下创建名为store的文件夹&#xff0c;里面的具体文件如下 featur…