Open SSL 3.0相关知识以及源码流程分析

news2025/6/6 11:31:13

Open SSL 3.0相关知识以及源码流程分析

编译

  • windows环境编译

1、工具安装

安装安装perl脚本解释器、安装nasm汇编器(添加到环境变量)、Visual Studio编译工具

安装dmake

 ppm install dmake # 需要过墙

2、开始编译

# 1、找到Visual Studio命令行编译工具目录 或者菜单栏直接启动对应架构的cmd程序
# D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build
# 找到合适的编译架构bat 双击 比如:vcvars32.bat

# 2、进入openssl目录
cd D:\openssl-openssl-3.1.0

# 3、perl生成对应的makefile
# -prefix 是编译后输出的路径,默认会生成到C:\Program Files (x86)目录
perl Configure VC-WIN32 --prefix=D:\openssl-openssl-3.1.0\mybuild

# 4、编译等待
nmake

# 5、安装到指定目录
# 编译好的文件安装到指定目录,默认是C:\Program Files (x86)\OpenSSL,如果是在C盘,运行控制台是需要有管理员权限
nmake install
  • Linux编译
# 1、解压进入目录
# 2、config配置
./config
# 3、编译
make
# 4、安装库到指定目录 /usr/local/include/openssl /usr/local/lib
make install
  • 基础使用

Open SSL 3.0支持国密sm2 sm3 sm4

包含对称加密、非对称加密、单向散列、伪随机、签名、密码交换、证书等一系列算法库。

applink错误处理

解决办法:

// 属性配置  -> C++ -> 预处理器   _CRT_SECURE_NO_WARNINGS
extern "C"
{
  #include <openssl/applink.c>
};

编码原理

  • Base16

用16进制来编码

static const char BASE16_ENC_TAB[] = "0123456789ABCDEF";
static const char BASE16_DEC_TAB[128] = {
	-1,											// 0
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	    // 1-10
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	    // 11-20
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	    // 21-30
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	    // 31-40
	-1, -1, -1, -1, -1, -1, -1,  0,  1,  2,	    // 41-50
   3,  4,  5,  6,  7,  8,  9, -1, -1, -1,	    // 51-60
	-1, -1, -1, -1, 10, 11, 12, 13, 14, 15,	    // 61-70
};

int base16Encode(const unsigned char* in, int size, char* out)
{
	for (int i = 0; i < size; i++)
	{
		// 一个字节取出高4位和低4位
		char h = in[i] >> 4; // 移位丢弃低位
		char low = in[i] & 0x0F; // & 去掉高位
		out[i * 2] = BASE16_ENC_TAB[h]; // 0~15映射到对应字符串
		out[i * 2 + 1] = BASE16_ENC_TAB[low];
	}
	// base16转码后空间扩大一倍  4位转成一个字符  1个字符转成2个字符
	return size * 2;
}

int base16Decode(const string& in, unsigned char* out)
{
	// 将两个字符拼接成一个字符
	for (int i = 0; i < in.size(); i += 2)
	{
		unsigned char ch = in[i];  // 高位转换的字符
		unsigned char cl = in[i + 1]; // 低位转换的字符
		unsigned char h = BASE16_DEC_TAB[ch];  // 转换成原来的值
		unsigned char l = BASE16_DEC_TAB[cl];

		// 两个4位拼成一个字符
		out[i / 2] = h << 4 | l;
	}
	return in.size() / 2;
}

int main(int argc, char* argv[])
{
	const unsigned char data[] = "测试Base16";
	int len = sizeof(data);
	char out1[1024] = { 0 };
	unsigned char out2[1024] = { 0 };
	cout << data << endl;
	int encode_result = base16Encode(data, len, out1);
	cout << "encode_result = " << encode_result << " out1:" << out1 << endl;

	int decode_result = base16Decode(out1, out2);
	cout << "decode_result = " << decode_result << " out2:" << out2 << endl;
	getchar();
	return 0;
}
  • Base64

二进制转字符串

原理:

把3个8位字节(3x8=24)转化为4个6位的字节(4x6=24),之后在6位的前面补两个0,形成8位一个字节的形式。如果剩下的字符不足3个字节,则用0填充,输出字符使用“=”,因此编码后输出的文本末尾可能会出现1或者2个“=”。

  • Open SSL bio接口

使用bio接口实现base64编码

#include "Base64.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <iostream>

int Base64::base64Encode(const unsigned char* in, int len, char* out_base64)
{
	if (!in || len <= 0 || !out_base64)
	{
		return 0;
	}
	// 内存源 source
	auto mem_bio = BIO_new(BIO_s_mem());
	if (!mem_bio)
	{
		return 0;
	}
	// base64 filter
  // BIO_new创建bio对象
  // BIO_f_base64封装了base64编码方法的BIO,写的时候编码,读的时候解码
  // BIO_s_mem 封装了内存操作的bio接口,包括对内存的读写操作
	auto b64_bio = BIO_new(BIO_f_base64());
	if (!b64_bio)
	{
		BIO_free(mem_bio);
		return 0;
	}
	// 形成bio链,连接两个对象到链表中b64_bio->mem_bio
	// b64-mem
	BIO_push(b64_bio, mem_bio);
	// 设置超过64字节不添加换行符, 解码需要对应的设置
	BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);

	// 写入到base64 filter进行编码,结果会传递到链表的下一个节点
	// 到mem中读取结果(链表头部代表了整个链表)
	// BIO_write 编码 3字节-> 4字节 不足3字节补充0和=
	// 编码数据每64字节会加\n 换行符, 默认结尾有换行符
	int re = BIO_write(b64_bio, in, len);
	if (re <= 0)
	{
		// 释放整个链表节点
		BIO_free_all(b64_bio);
		return 0;
	}
	// 刷新缓存,写入链表的mem
	BIO_flush(b64_bio);
	// 从链表源内存读取
	int outsize = 0;
	BUF_MEM* p_data = 0;
	BIO_get_mem_ptr(b64_bio, &p_data);
	if (p_data)
	{
		memcpy(out_base64, p_data->data, p_data->length);
		outsize = p_data->length;
	}
	BIO_free_all(b64_bio);
	return outsize;
}


int Base64::base64Decode(const char* in, int len, unsigned char* out_data)
{
	if (!in || len <= 0 || !out_data)
	{
		return 0;
	}

	// 内存源 密文
  // 创建一个内存型的bio对象
	auto mem_bio = BIO_new_mem_buf(in, len);
	if (!mem_bio)
	{
		return 0;
	}
	// base64 filter
	auto b64_bio = BIO_new(BIO_f_base64());
	if (!b64_bio)
	{
		BIO_free(mem_bio);
		return 0;
	}

	BIO_push(b64_bio, mem_bio);
	// 与编码对应
	BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);

	// 读取解码
	size_t size = 0;
  // BIO_read_ex 从bio接口读出len字节到buf中
	int re = BIO_read_ex(b64_bio, out_data, len, &size);
	BIO_free_all(b64_bio);
	return size;
}


// main.cpp
int main(int argc, char* argv[])
{
	Base64 *base = new Base64();
	const unsigned char data[] = "测试Base64阿斯顿发到付亲戚212阿发的顺丰到付412341324321432141243按时发放";
	int len = sizeof(data);
	char out[1024] = { 0 };
	int res = base->base64Encode(data, len, out);
	if (res > 0)
	{
		cout << "[" << out <&

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

股指期货合约价值怎么算?

股指期货合约价值就是你买一手股指期货合约&#xff0c;理论上值多少钱。这个价值是根据期货的价格和合约乘数来计算的。就好比你买了一斤苹果&#xff0c;价格是5块钱一斤&#xff0c;那你买一斤就得付5块钱。股指期货也是一样&#xff0c;只不过它的计算稍微复杂一点点。 一…

【QT】使用QT帮助手册找控件样式

选择帮助—》输入stylesheet(小写)—》选择stylesheet—》右侧选择Qt Style Sheets Reference 2.使用CtrlF—》输入要搜索的控件—》点击Customizing QScrollBar 3.显示参考样式表–》即可放入QT-designer的样式表中

计算机网络(5)——数据链路层

1.概述 数据链路层负责一套链路上从一个节点向另一个物理链路直接相连的相邻节点传输数据报。换言之&#xff0c;主要解决相邻节点间的可靠数据传输 节点(nodes)&#xff1a;路由器和主机 链路(links)&#xff1a;连接相邻节点的通信信道 2.数据链路层服务 2.1 组帧 组帧(fra…

VuePress完美整合Toast消息提示

VuePress 整合 Vue-Toastification 插件笔记 记录如何在 VuePress 项目中整合使用 vue-toastification 插件&#xff0c;实现优雅的消息提示。 一、安装依赖 npm install vue-toastification或者使用 yarn&#xff1a; yarn add vue-toastification二、配置 VuePress 客户端增…

adb 连不上真机设备问题汇总

问题一、无法弹出 adb 调试授权弹窗 详细描述&#xff1a; 开发者选项中已打开 usb 调试&#xff0c;仅充电模式下 usb 调试也已打开&#xff0c;电脑通过 usb 连上手机后&#xff0c;一直弹出 adb 调试授权弹窗&#xff0c;尝试取消授权再次连接&#xff0c;还是无法弹出问题…

[yolov11改进系列]基于yolov11引入注意力机制SENetV1或者SENetV2的python源码+训练源码

本文给大家带来的改进机制是SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型Q&#xff0c;而是一个可以和现有的任何一个模型相结合的模块&#xff08;可以看作是一种…

鸿蒙仓颉语言开发实战教程:商城搜索页

大家好&#xff0c;今天要分享的是仓颉语言商城应用的搜索页。 搜索页的内容比较多&#xff0c;都有点密集恐惧症了&#xff0c;不过我们可以从上至下将它拆分开来&#xff0c;逐一击破。 导航栏 搜索页的的最顶部是导航栏&#xff0c;由返回按钮和搜索框两部分组成,比较简单…

图像去雾数据集总汇

自然去雾数据集 部分的数据清洗可以看这里&#xff1a;图像去雾数据集的下载和预处理操作 RESIDE-IN 将ITS作为训练集&#xff0c;SOTSindoor作为测试集。训练集13990对&#xff0c;验证集500对。 目前室内sota常用&#xff0c;最高已经卷到PSNR-42.72 最初应该是dehazefo…

网络攻防技术十四:入侵检测与网络欺骗

文章目录 一、入侵检测概述二、入侵系统的分类三、入侵检测的分析方法1、特征检测&#xff08;滥用检测、误用检测&#xff09;2、异常检测 四、Snort入侵检测系统五、网络欺诈技术1、蜜罐2、蜜网3、网络欺骗防御 六、简答题1. 入侵检测系统对防火墙的安全弥补作用主要体现在哪…

C++笔记-C++11(一)

1.C11的发展历史 C11 是 C 的第⼆个主要版本&#xff0c;并且是从 C98 起的最重要更新。它引⼊了⼤量更改&#xff0c;标准化了既有实践&#xff0c;并改进了对 C 程序员可⽤的抽象。在它最终由 ISO 在 2011 年 8 ⽉ 12 ⽇采纳前&#xff0c;⼈们曾使⽤名称“C0x”&#xff0c;…

JVM 类初始化和类加载 详解

类初始化和类加载 类加载的时机 加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的&#xff0c;类型的加载过程必须按照这种顺序按部就班地开始&#xff0c;而解析阶段则不一定&#xff1a;它在某些情况下可以在初始化阶段之后再开始&#xff08;懒解析&#xff09;&am…

B站缓存视频数据m4s转mp4

B站缓存视频数据m4s转mp4 结构分析 结构分析 在没有改变数据存储目录的情况下&#xff0c;b站默认数据保存目录为&#xff1a; Android->data->tv.danmaku.bili->download每个文件夹代表一个集合的视频&#xff0c;比如&#xff0c;我下载的”java从入门到精通“&…

DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_天气预报日历示例(CalendarView01_18)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

【机器学习】主成分分析 (PCA)

目录 一、基本概念 二、数学推导 2.1 问题设定&#xff1a;寻炸最大方差的投影方向 2.2 数据中心化 2.3 目标函数&#xff1a;最大化投影后的方差 2.4 约束条件 2.5 拉格朗日乘子法 ​编辑 2.6 主成分提取 2.7 降维公式 三、SVD 四、实际案例分析 一、基本概念 主…

二叉树-104.二叉树的最大深度-力扣(LeetCode)

一、题目解析 这里需要注意根节点的深度是1&#xff0c;也就是说计算深度的是从1开始计算的 二、算法原理 解法1&#xff1a;广度搜索&#xff0c;使用队列 解法2&#xff1a;深度搜索&#xff0c;使用递归 当计算出左子树的深度l&#xff0c;与右子树的深度r时&#xff0c;…

物料转运人形机器人适合应用于那些行业?解锁千行百业的智慧物流革命

当传统物流设备困于固定轨道&#xff0c;当人力搬运遭遇效率与安全的天花板&#xff0c;物料转运人形机器人正以颠覆性姿态重塑产业边界。富唯智能凭借GRID大模型驱动的"感知-决策-执行"闭环系统&#xff0c;让物料流转从机械输送升级为智慧调度——这不仅是工具的革…

时序预测模型测试总结

0.背景描述 公司最近需要在仿真平台上增加一些AI功能&#xff0c;针对于时序数据&#xff0c;想到的肯定是时序数据处理模型&#xff0c;典型的就两大类&#xff1a;LSTM 和 tranformer 。查阅文献&#xff0c;找到一篇中石化安全工程研究院有限公司的文章&#xff0c;题目为《…

第四十五天打卡

知识点回顾&#xff1a; tensorboard的发展历史和原理 tensorboard的常见操作 tensorboard在cifar上的实战&#xff1a;MLP和CNN模型 效果展示如下&#xff0c;很适合拿去组会汇报撑页数&#xff1a; 作业&#xff1a;对resnet18在cifar10上采用微调策略下&#xff0c;用tensor…

springboot mysql/mariadb迁移成oceanbase

前言&#xff1a;项目架构为 springbootmybatis-plusmysql 1.部署oceanbase服务 2.springboot项目引入oceanbase依赖&#xff08;即ob驱动&#xff09; ps&#xff1a;删除原有的mysql/mariadb依赖 <dependency> <groupId>com.oceanbase</groupId> …

npm install 报错:npm error: ...node_modules\deasync npm error command failed

npm install 时报错如下&#xff1a; 首先尝试更换node版本&#xff0c;当前node版本20.15.0&#xff0c;更换node版本为16.17.0。再次执行npm install安装成功