openssl3.2 - exp - zlib

news2025/6/23 7:30:08

文章目录

    • 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

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

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

相关文章

无人机低空数字摄影测量系统

一、 系统概述 系统完全基于IDL设计实现&#xff0c;包括界面布局到人机交互再到底层核心函数功能。整体设计框架基于数字摄影测量的专业处理流程&#xff0c;实现了数据输入、数据预处理、影像信息检测、空间定向、地形三维建模、专题信息提取、成果输出与更新等功能。同时为…

Android 10.0 系统设置语言和输入法菜单Launage语言列表增加支持多种英语语言功能

1.前言 在10.0的系统ROM产品定制化开发中,在系统中的语言和输入法菜单中,在添加语言的默认列表中对于同一类型的语言就可以 会出现一中语言,比如多种英语类型 就显示的不全,所以要求显示所有的英语类型,这样就需要了解语言列表的加载流程 然后加载所有的英语类型,接下来…

【深度学习】多层感知机与卷积神经网络解析

引言&#xff1a; 在人工智能的宏伟画卷中&#xff0c;深度学习如同一笔瑰丽而深邃的色彩&#xff0c;为这幅画增添了无限的生命力和潜能。作为支撑这一领域核心技术的基石&#xff0c;多层感知机&#xff08;MLP&#xff09;和卷积神经网络&#xff08;CNN&#xff09;在模仿人…

安全风险攻击面管理如何提升企业网络弹性?

从研究人员近些年的调查结果来看&#xff0c;威胁攻击者目前非常善于识别和利用最具有成本效益的网络入侵方法&#xff0c;这就凸显出了企业实施资产识别并了解其资产与整个资产相关的安全态势的迫切需要。 目前来看&#xff0c;为了在如此复杂的网络环境中受到最小程度上的网络…

Lumos学习python第九课:VSCode+Anaconda

注意Anaconda版本和Python版本的对应关系&#xff0c;同一个Anaconda可以支持多个Python版本&#xff0c; 注&#xff1a;现在vscode已原生支持jupyter notebook&#xff08;要求Python版本>3.6&#xff09; Anaconda在Python解析器的基础上封装了很多Python包&#xff0c…

【CVE-2010-2883】进行钓鱼攻击的研究

最近作业中研究APT攻击&#xff0c;了解到2011年前后披露的LURID-APT&#xff0c;其中敌手利用了各种版本的文件查看器的漏洞实现攻击。CVE-2010-2883就是其中被利用的一个adobe reader的漏洞。特此复现&#xff0c;更好的研究和防范APT攻击。 本文仅仅是对相关漏洞利用的学习…

基于JAVA的校园失物招领平台

采用技术 基于JAVA的校园失物招领平台的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringMVCMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 管理员功能 论坛管理 失物认领管理 寻物启事管理 用户管理 失物…

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

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

用html实现一个动态的文字框

<!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>一个动态的文字框动画</title><link rel"stylesheet" href"./style.css"></head> <body> <link rel…

混合云构建-如何通过Site to Site VPN 连接 AWS 和GCP云并建立一个高可用的VPN通信

如果我们的业务环境既有AWS云又有GCP云,那么就需要将他们打通,最经济便捷的方式就是通过Site-to-Site VPN连接AWS和GCP云,你需要在两个云平台上分别配置VPN网关,并建立一个VPN隧道来安全地连接这两个环境,我们下面演示一个高可用场景下的S2S VPN线路构建,采用动态BGP协议…

【数据结构(四)】链表经典练习题

❣博主主页: 33的博客❣ ▶️文章专栏分类:数据结构◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你学更多数据结构知识 目录 1.前言2.删除值为key的所有结点3.反转链表4.返回中间结点5.输出倒数第k个结点6.链表…

C++11 设计模式1. 模板方法(Template Method)模式学习。UML图

一 什么是 "模板方法&#xff08;Template Method&#xff09;模式" 在固定步骤确定的情况下&#xff0c;通过多态机制在多个子类中对每个步骤的细节进行差异化实现&#xff0c;这就是模板方法模式能够达到的效果。 模板方法模式属于&#xff1a;行为型模式。 二 &…

Hive的分区与排序

一、Hive分区 1.引入&#xff1a; 在大数据中&#xff0c;最常见的一种思想就是分治&#xff0c;我们可以把大的文件切割划分成一个个的小的文件&#xff0c;这样每次操作一个个小的文件就会很容易了&#xff0c;同样的道理&#xff0c;在hive当中也是支持这种思想的&#xff…

SQL注入sqli_labs靶场第三题

?id1and 11 and 11和?id1and 11 and 11进行测试如果11页面显示正常和原页面一样&#xff0c;并且12页面报错或者页面部分数据显示不正常&#xff0c;那么可以确定此处为字符型注入。 根据报错信息判断为单引号带括号注入 联合查询&#xff1a; 猜解列名 ?id1) order by 3-…

实战项目——智慧社区(二)之 物业管理

分页 用于分页封装的实体类 Data public class PageVO {private Long totalCount;private Long pageSize;private Long totalPage;private Long currPage;private List list; }分页的相关配置 package com.qcby.community.configuration;import com.baomidou.mybatisplus.e…

利用Sentinel解决雪崩问题(二)隔离和降级

前言&#xff1a; 虽然限流可以尽量避免因高并发而引起的服务故障&#xff0c;但服务还会因为其它原因而故障。而要将这些故障控制在一定范围避免雪崩&#xff0c;就要靠线程隔离(舱壁模式)和熔断降级手段了&#xff0c;不管是线程隔离还是熔断降级&#xff0c;都是对客户端(调…

物联网实验

实验1 基于ZStack光敏传感器实验 1.实验目的 我们通过上位机发指令给协调器&#xff0c;协调器把串口接收到的指令通过Zigbee协议无线发送给带有光敏传感器的终端节点&#xff0c;获取到数据以后把数据返回给上位机&#xff0c;实现无线获取数据的目的。 2.实验设备 硬件&a…

Vue2和Vue3组件通信:父子与兄弟间的桥梁

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

Chatgpt掘金之旅—有爱AI商业实战篇|在线辅导业务|(十三)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业播客剧本写作服务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。…

分类模型绘制决策边界、过拟合、评价指标

文章目录 1、线性逻辑回归决策边界1.2、使用自定义函数绘制决策边界1.3、三分类的决策边界1.4、多项式逻辑回归决策边界 2、过拟合和欠拟合2.2、欠拟合2.3、过拟合 3、学习曲线4、交叉验证5、泛化能力6、混淆矩阵7、PR曲线和ROC曲线 x2可以用x1来表示 1、线性逻辑回归决策边界 …