openssl3.2 - exp - zlib

文章目录

    • openssl3.2 - exp - zlib
    • 概述
    • 笔记
    • 命令行实现
    • 程序实现
    • 备注 - 压缩时无法base64
    • 压缩时无法带口令压缩
    • 实现 - 对buffer进行压缩和解压缩
    • 测试效果
    • 工程实现
    • main.cpp
    • COsslZlibBuffer.h
    • COsslZlibBuffer.cpp
    • 总结
    • END

openssl3.2 - exp - zlib

概述

客户端和服务端进行数据交换时,如果压缩一下要交互的数据,可以节省带宽。
如果数据是文本型, 压缩率特别大。

以前用zlib库单独实验过,写起来还挺麻烦的。

正好这次已经将zlib特性加入了openssl(openssl3.2 - 编译 - zlib.dll不要使用绝对路径), 试一下用openssl来压缩/解压缩数据方便不?

笔记

命令行实现

// openssl zip help
openssl zlib --help

// zip
openssl zlib -e -in test.txt -out test.txt.zlib -pass pass:my_pwd

// unzip
openssl zlib -d -in test.txt.zlib -out test.txt.zlib.unzlib -pass pass:my_pwd

程序实现

先看一下openssl.exe的实现

备注 - 压缩时无法base64

如果选了zlib, 就不能选base64.
如果想zlib后,再base64, 需要单独对输出结果进行base64(https://lostspeed.blog.csdn.net/article/details/136881319).

		if (do_zlib)
			base64 = 0;

压缩时无法带口令压缩

压缩时口令不起作用,因为可以不带口令解开。

openssl zlib -d -in test.txt.zlib -out test.txt.zlib.unzlib

如果想将压缩后的内容加密,需要自己单独对压缩后的内容加密。

实现 - 对buffer进行压缩和解压缩

测试效果

org:
0000 - 68 65 6c 6c 6f 20 6f 70-65 6e 73 73 6c 33 2e 32   hello openssl3.2
0010 - 20 7a 6c 69 62 0a                                  zlib.
zip:
0000 - 78 9c cb 48 cd c9 c9 57-c8 2f 48 cd 2b 2e ce 31   x..H...W./H.+..1
0010 - d6 33 52 a8 ca c9 4c e2-02 00 5e 4e 07 a7         .3R...L...^N..
unzip:
0000 - 68 65 6c 6c 6f 20 6f 70-65 6e 73 73 6c 33 2e 32   hello openssl3.2
0010 - 20 7a 6c 69 62 0a                                  zlib.
free mem_hook map, g_mem_hook_map.size() = 0, no openssl API call memory leak

工程实现

test prj is exp034_zlib
在这里插入图片描述

main.cpp

/*!
* \file main.cpp
*/

#include "ossl/my_openSSL_lib_v1.1.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include "COsslZlibBuffer.h"

void my_openssl_app();

int main(int argc, char** argv)
{
	setvbuf(stdout, NULL, _IONBF, 0); // 清掉stdout缓存, 防止调用printf时阻塞
	mem_hook();

	my_openssl_app();

	mem_unhook();

	return 0;
}

void my_openssl_app()
{
	bool b_rc = false;
	int i_rc = 0;
	COsslZlibBuffer zlib;
	
	uint8_t szBuf[0x1000];
	int lenBuf = 0;
	
	uint8_t* pBufOut1 = NULL;
	int lenBufOut1 = 0;

	uint8_t* pBufOut2 = NULL;
	int lenBufOut2 = 0;

	strcpy((char*)szBuf, "hello openssl3.2 zlib\n");
	lenBuf = strlen((char*)szBuf);

	printf("org:\n");
	BIO_dump_fp(stdout, szBuf, lenBuf);

	b_rc = zlib.zip(szBuf, lenBuf, pBufOut1, lenBufOut1);
	assert(b_rc);

	printf("zip:\n");
	BIO_dump_fp(stdout, pBufOut1, lenBufOut1);

	b_rc = zlib.unzip(pBufOut1, lenBufOut1, pBufOut2, lenBufOut2);
	assert(b_rc);

	printf("unzip:\n");
	BIO_dump_fp(stdout, pBufOut2, lenBufOut2);

	assert(lenBufOut2 == lenBuf);
	i_rc = memcmp(szBuf, pBufOut2, lenBuf);
	assert(0 == i_rc);

	if (NULL != pBufOut1)
	{
		OPENSSL_free(pBufOut1);
		pBufOut1 = NULL;
	}

	if (NULL != pBufOut2)
	{
		OPENSSL_free(pBufOut2);
		pBufOut2 = NULL;
	}
}

COsslZlibBuffer.h

//! \file COsslZlibBuffer.h

#ifndef __C_OSSL_ZLIB_BUFFER_H__
#define __C_OSSL_ZLIB_BUFFER_H__

#include <stdlib.h>
#include <stdio.h>
#include <cstdint> // for uint8_t

#ifndef IN
#define IN
#endif // !IN

#ifndef OUT
#define OUT
#endif // !OUT

#include "openssl/bio.h"

class COsslZlibBuffer
{
public:
	COsslZlibBuffer();
	virtual ~COsslZlibBuffer();

	// 出参指针调用者负责释放(OPENSSL_free())
	bool zip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut);
	bool unzip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut);

private:
	bool zipOpt(bool isZip, IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut);

	size_t bio_get_length(BIO* bio);
	bool bio_to_buf(BIO* bio, uint8_t*& pBuf, int& lenBuf);
};

#endif // #ifndef __C_OSSL_ZLIB_BUFFER_H__

COsslZlibBuffer.cpp

//! \file COsslZlibBuffer.cpp

#include "COsslZlibBuffer.h"

#include "openssl/bio.h"
#include "openssl/comp.h"

COsslZlibBuffer::COsslZlibBuffer()
{

}

COsslZlibBuffer::~COsslZlibBuffer()
{

}

bool COsslZlibBuffer::zip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut)
{
	return zipOpt(true, pBuf, lenBuf, pBufOut, lenBufOut);
}

bool COsslZlibBuffer::unzip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut)
{
	return zipOpt(false, pBuf, lenBuf, pBufOut, lenBufOut);
}

bool COsslZlibBuffer::zipOpt(bool isZip, IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut)
{
	bool b_rc = false;
	BIO* bio_zip = NULL;
	BIO* bio_in = NULL;
	BIO* bio_out = NULL;

	BIO* bio_read = NULL;
	BIO* bio_write = NULL;

	uint8_t szBuf[0x1000];
	int iCntRead = 0;
	int iCntWasWrite = 0;

	do {
		if ((NULL == pBuf) || (lenBuf <= 0))
		{
			break;
		}

		lenBufOut = 0;
		bio_zip = BIO_new(BIO_f_zlib());
		if (NULL == bio_zip)
		{
			break;
		}

		bio_in = BIO_new_mem_buf(pBuf, lenBuf);
		if (NULL == bio_in)
		{
			break;
		}

		bio_out = BIO_new(BIO_s_mem());
		if (NULL == bio_out)
		{
			break;
		}

		if (isZip)
		{
			bio_read = bio_in;
			bio_write = BIO_push(bio_zip, bio_out);  // write to bio link header, out form bio link tail
		}
		else {
			bio_read = BIO_push(bio_zip, bio_in);
			bio_write = bio_out;
		}

		do {
			iCntRead = BIO_read(bio_read, szBuf, (int)sizeof(szBuf));
			if (iCntRead <= 0)
			{
				break;
			}

			iCntWasWrite = BIO_write(bio_write, szBuf, iCntRead);
			if (iCntWasWrite != iCntRead)
			{
				goto END;
			}
		} while (true);

		if (!BIO_flush(bio_write))
		{
			break;
		}

		// 如果读bio_write, 得到的是写入的数据, 而不是处理完的输出数据
		if (!bio_to_buf(bio_out, pBufOut, lenBufOut))
		{
			break;
		}

		/*
		do_zlib = 1;
		enc = 1;
		saltlen = PKCS5_SALT_LEN;
		dgst = (EVP_MD *)EVP_sha256();
		iter = 1;
			if (do_zlib)
			base64 = 0;
			BIO *bzl = NULL;
			bzl = BIO_new(BIO_f_zlib()
			wbio = BIO_push(bzl, wbio);
				while (BIO_pending(rbio) || !BIO_eof(rbio)) {
			inl = BIO_read(rbio, (char *)buff, bsize);
			if (inl <= 0)
				break;
			if (!streamable && !BIO_eof(rbio)) {
	//	BIO_printf(bio_err, "Unstreamable cipher mode\n");
	//	goto end;
	//}
	//if (BIO_write(wbio, (char*)buff, inl) != inl) {
	//	BIO_printf(bio_err, "error writing output file\n");
	//	goto end;
	//}
	//if (!streamable)
	//break;
	//	}

	BIO_flush(wbio)
			if (enc)
				wbio = BIO_push(bzl, wbio);
			else
				rbio = BIO_push(bzl, rbio);
		*/


		b_rc = true;
	} while (false);

END:
	if (NULL != bio_read)
	{
		BIO_free_all(bio_read);
		bio_read = NULL;
	}

	if (NULL != bio_write)
	{
		BIO_free_all(bio_write);
		bio_write = NULL;
	}

	return b_rc;
}

size_t COsslZlibBuffer::bio_get_length(BIO* bio)
{
	size_t bio_length = 0;

	do {
		if (NULL == bio)
		{
			break;
		}

		// BIO_seek(bio, 0);
		bio_length = BIO_ctrl_pending(bio);
	} while (false);

	return bio_length;
}

bool COsslZlibBuffer::bio_to_buf(BIO* bio, uint8_t*& pBuf, int& lenBuf)
{
	bool b_rc = false;
	int i_rc = 0;

	do {
		if (NULL == bio)
		{
			break;
		}

		lenBuf = (int)bio_get_length(bio);
		pBuf = (uint8_t*)OPENSSL_malloc(lenBuf + 1);
		if (NULL == pBuf)
		{
			break;
		}

		pBuf[lenBuf] = '\0';
		i_rc = BIO_read(bio, pBuf, lenBuf);
		BIO_seek(bio, 0); // ! 读完了, 将数据读指针恢复.

		b_rc = (i_rc == lenBuf);
	} while (false);

	return b_rc;
}

总结

用openssl做zip操作比直接用zlib库操作方便多了。
openssl的封装真优秀。

END

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

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

相关文章

数据库的负载均衡,高可用实验

一 高可用负载均衡集群数据库实验 1.实验拓扑图 2.实验准备(同一LAN区段)&#xff08;ntp DNS&#xff09; 客户端&#xff1a;IP&#xff1a;192.168.1.5 下载&#xff1a;MariaDB 负载均衡器&#xff1a;IP&#xff1a;192.168.1.1 下载&#xff1a;keepalived ipvsadm I…

鸿蒙实战开发-如何实现选择并查看文档与媒体文件

介绍 应用使用ohos.file.picker、ohos.multimedia.mediaLibrary、ohos.file.fs 等接口&#xff0c;实现了picker拉起文档编辑保存、拉起系统相册图片查看、拉起视频并播放的功能。 效果预览 使用说明&#xff1a; 在首页&#xff0c;应用展示出最近打开过的文档信息&#xf…

【JavaWeb】Servlet与过滤器

目录 ServletServlet做了什么JSP与Servlet的关系主要Servlet API介绍如何创建ServletServlet中主要方法ServletRequestServletResponseServletConfig Servlet生命周期Servlet创建Servlet部署与运行 ServletConfig类ServletConfig类的三大作用 ServletContext类ServletContext类…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之八 简单视频素描效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之八 简单视频素描效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之八 简单视频素描效果 一、简单介绍 二、简单指定视频某片段快放效果实现原理 三、简单指定视频某…

web安全学习笔记(9)

记一下第十三课的内容。 准备工作&#xff1a;在根目录下创建template目录&#xff0c;将login.html放入其中&#xff0c;在该目录下新建一个reg.html。在根目录下创建一个function.php 一、函数声明与传参 PHP中的函数定义和其他语言基本上是相同的。我们编辑function.php …

stm32f103c8t6学习笔记(学习B站up江科大自化协)-看门狗【WDG】

硬件部分 一、看门狗简介 看门狗-WDG&#xff08;watchdog&#xff09; 看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入长时间的罢工状态…

相机参数的意义

相机标定的意义&#xff1a; 相机标定&#xff1a;使用带有pattern的标定板来求解相机参数的过程&#xff1b;用一个简化的数学模型来代表复杂的三维到二维的成像过程&#xff1b;相机参数包括&#xff1a;相机内参&#xff08;焦距等&#xff09;&#xff0c;外参&#xff08…

为什么需要SOCKS代理?

在数字化时代&#x1f310;&#xff0c;随着网络安全威胁的不断演进和增加&#xff0c;保护个人隐私和数据安全成为了互联网用户的一大挑战&#x1f6e1;️。在寻求增强在线安全和隐私的解决方案时&#xff0c;SOCKS代理成为了一个关键的技术工具&#x1f511;。本文旨在详细探…

代码随想录:栈与队列4-6

20.有效的括号 题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一…

什么是容器安全,该怎么进行容器安全的检测防护

随着容器技术的迅速发展和普及&#xff0c;越来越多的企业开始采用容器化解决方案来优化应用部署、提高资源利用率和降低成本。然而&#xff0c;在对大规模部署和使用容器应用来提升业务系统开发速度的时候&#xff0c;大量的数据对象、多种安全风险都需要检测&#xff0c;容器…

Spark_SparkSql写入Oracle_Undefined function.....将长字符串写入Oracle中方法..

在使用Spark编写代码将读库处理然后写入Oracle中遇到了诸多小bug,很磨人。shit!! 实测1&#xff1a;TO_CLOB(a3) 代码样例 --这是一个sparksql写入hive的一个小逻辑&#xff0c;我脱敏了噻 SELECT a1, a2, TO_CLOB(a3) AS clob_data, TO_DATE(a4) AS time FROM table1 WHERE…

外包干了15天,技术倒退明显

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四年的功能…

海外软文通稿代发 - 大舍传媒

引言 在当今高度信息化的时代&#xff0c;企业和个人品牌形象的塑造与传播变得越来越重要。为了在国际舞台上获得更大的竞争优势&#xff0c;许多企业和品牌纷纷将视线投向了国外市场。而在这个过程中&#xff0c;专业的软文通稿代发服务成为了他们的得力助手。本文将向您介绍…

恒创科技:香港服务器CPU核心数如何选?越多越好吗?

​  谈到 CPU“核心”是完成所有处理的组件&#xff0c;程序能否顺利运行的第一因素是你有多少个核心。但由于不同的计算任务占用不同的资源&#xff0c;所以如果您打算简单地创建小型网站或者其他请求处理数据也不高的业务&#xff0c;那么您的基本型号应该包含 1、2 核已经…

云计算重要概念之:虚拟机、网卡、交换机、路由器、防火墙

一、虚拟机 (Virtual Machine, VM) 1.主流的虚拟化软件&#xff1a; 虚拟化软件通过在单个物理硬件上创建和管理多个虚拟环境&#xff08;虚拟机&#xff09;&#xff0c;实现资源的高效利用、灵活部署、隔离安全以及便捷管理&#xff0c;是构建云计算和现代化数据中心的核心…

【电控笔记4】拉普拉斯-传递函数-pid

数据标幺化 拉普拉斯变换 欧拉公式 常见s变换 s变换性质 pid分析 p控制&#xff0c;存在稳态误差 可以求出p的取值范围p>-1&#xff0c;否则发散 pi消除稳态误差 把kp换成Gs 只用pi控制&#xff0c;不加微分的原因&#xff1a; 微分之后&#xff0c;噪声增大高频噪声频率…

【力扣】104. 二叉树的最大深度、111. 二叉树的最小深度

104. 二叉树的最大深度 题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输…

机器学习与自主系统

Darpa人工智能中有两个重要方向&#xff0c;一是机器学习&#xff0c;另一个就是自主系统。但真实博弈环境下&#xff0c;更重要的是人机融合体系… 机器学习是一种人工智能的分支&#xff0c;通过使用统计学和数学模型来让计算机系统学习和改进其性能。它可以让计算机从数据中…

FreeRTOS创建第一个程序

使用freeRTOS创建任务时使用如下函数 函数的参数 创建一个FreeRTOS任务点亮led灯实现led灯500毫秒翻转一次 具体的代码实现 #include "stm32f10x.h" // Device header #include "Delay.h" #include "freeRTOS.h" #include &quo…

【bash】linux使用环境变量拼接字符串错误

有如下脚本init-env.sh #!/bin/bash export HADOOP_HOME/opt/hadoop export HADOOP_CONF$HADOOP_HOME/conf执行结果&#xff1a; source init-env.sh echo $HADOOP_CONF_DIR # 得到结果&#xff1a;conf/hadoop&#xff0c;预期因该是/opt/hadoop/conf原因就是linux下使用了w…