班级响应式网站html格式,凡科网站建设步骤,怎么盗用网站,雁塔免费做网站文章目录 openssl3.2 - exp - zlib概述笔记命令行实现程序实现备注 - 压缩时无法base64压缩时无法带口令压缩实现 - 对buffer进行压缩和解压缩测试效果工程实现main.cppCOsslZlibBuffer.hCOsslZlibBuffer.cpp总结备注 - 解压可以替代完整性校验备注 - 多次压缩没作用备注 - 和7… 文章目录 openssl3.2 - exp - zlib概述笔记命令行实现程序实现备注 - 压缩时无法base64压缩时无法带口令压缩实现 - 对buffer进行压缩和解压缩测试效果工程实现main.cppCOsslZlibBuffer.hCOsslZlibBuffer.cpp总结备注 - 解压可以替代完整性校验备注 - 多次压缩没作用备注 - 和7zip的压缩性能的比较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.hvoid 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.hclass 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.hCOsslZlibBuffer::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);elserbio 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的封装真优秀。
备注 - 解压可以替代完整性校验 // 测试zip内容变了之后是否还能正常解压// 实验过了, 随便改一个字节都无法解压成功pBufOut1[lenBufOut1 / 2 - 1] pBufOut1[lenBufOut1 /2 - 1] 1;b_rc zlib.unzip(pBufOut1, lenBufOut1, pBufOut3, lenBufOut3);assert(b_rc);实验过了, 将压缩后的内容随便改一个字节(头部附近尾部附近内容中部附近)再解压都会失败。 如果这样的话那就不用特意做hash来确认内容是否被无意中修改。
备注 - 多次压缩没作用
在第一次压缩后尝试将压缩结果再压缩长度反而增加了一点。 说明一次压缩就够了。
备注 - 和7zip的压缩性能的比较 // 因为样本比较小(2816字节), 用7zip分别极限压缩成.7z和.zip, 好不多少// .zip 1526字节// .7zip 1481字节// 算了就用openssl3.2自带的zip压缩吧// 用openssl自带的zip操作(2816 1391), 比7zip的极限压缩还优秀..., 惊讶END