openssl3.2 - exp - aes-128-cbc

文章目录

    • openssl3.2 - exp - aes-128-cbc
    • 概述
    • 笔记
    • openssl 命令行实现
    • 简单直白的实现
      • 简单直白的实现 - 测试效果
      • 简单直白的实现 - 测试工程
    • 周全灵活的实现
      • 周全灵活的实现 - 测试效果
      • 周全灵活的实现 - 测试工程
    • END

openssl3.2 - exp - aes-128-cbc

概述

想将工程中用到的字符串明文用openssl的对称加密算法加密一下, 防止逆向静态分析, 只作为字符串编码/解码的作用.
只是为了防止逆向静态分析, 起到一个编码/解码作用, 不介意别人知道密钥是啥.

看了一下openssl性能(AES性能大概是2000MB/秒, AES256比AES128稍低)

D:\my_dev\my_local_git_prj\study\openSSL\exp\exp029_enc\aes-128-cbc\doc>openssl speed -mlock -seconds 1 -bytes 4096 aes-128-cbc
Doing aes-128-cbc ops for 1s on 4096 size blocks: 567655 aes-128-cbc ops in 1.02s
version: 3.2.0
built on: Sun Feb 25 02:20:27 2024 UTC
options: bn(64,64)
compiler: cl  /Zi /Fdossl_static.pdb /Gs0 /GF /Gy /MDd /W3 /wd4090 /nologo /Od -DLIBZ=".\\\\my_zlib_1d3.dll" -DL_ENDIAN -DOPENSSL_PIC -D"OPENSSL_BUILDING_OPENSSL" -D"ZLIB" -D"ZLIB_SHARED" -D"OPENSSL_SYS_WIN32" -D"WIN32_LEAN_AND_MEAN" -D"UNICODE" -D"_UNICODE" -D"_CRT_SECURE_NO_DEPRECATE" -D"_WINSOCK_DEPRECATED_NO_WARNINGS" -D"DEBUG" -D"_DEBUG" -I"D:\\my_dev\\lib\\zlib_1d3"
CPUINFO: OPENSSL_ia32cap=0x7ffaf3ffffebffff:0x18c07fcef3bfa7eb
The 'numbers' are in 1000s of bytes per second processed. // 处理的“数字”以每秒1000字节为单位
type           4096 bytes
aes-128-cbc    2289343.88k => 2289343.88 * 1000 / 1024 / 1024 =   2183 MB/秒D:\my_dev\my_local_git_prj\study\openSSL\exp\exp029_enc\aes-128-cbc\doc>openssl speed -mlock -seconds 1 -bytes 4096 aes-256-cbc
Doing aes-256-cbc ops for 1s on 4096 size blocks: 414597 aes-256-cbc ops in 1.02s
version: 3.2.0
built on: Sun Feb 25 02:20:27 2024 UTC
options: bn(64,64)
compiler: cl  /Zi /Fdossl_static.pdb /Gs0 /GF /Gy /MDd /W3 /wd4090 /nologo /Od -DLIBZ=".\\\\my_zlib_1d3.dll" -DL_ENDIAN -DOPENSSL_PIC -D"OPENSSL_BUILDING_OPENSSL" -D"ZLIB" -D"ZLIB_SHARED" -D"OPENSSL_SYS_WIN32" -D"WIN32_LEAN_AND_MEAN" -D"UNICODE" -D"_UNICODE" -D"_CRT_SECURE_NO_DEPRECATE" -D"_WINSOCK_DEPRECATED_NO_WARNINGS" -D"DEBUG" -D"_DEBUG" -I"D:\\my_dev\\lib\\zlib_1d3"
CPUINFO: OPENSSL_ia32cap=0x7ffaf3ffffebffff:0x18c07fcef3bfa7eb
The 'numbers' are in 1000s of bytes per second processed.
type           4096 bytes
aes-256-cbc    1672063.32k

用openssl speed 列出的算法(openssl3.2 - exp - openssl speed test), 想选其他强度更低(速度更快)的其他对称加密算法, 好像没有啊. 非主流的算法, 用openssl speed都不能测试

那就拿AES128来弄吧.

笔记

openssl 命令行实现

// enc
openssl enc -aes-128-cbc -e -in pt.txt -out pt.txt.enc -k my_pwd_for_enc -pbkdf2// dec
openssl enc -aes-128-cbc -d -in pt.txt.enc -out pt.txt.enc.dec -k my_pwd_for_enc -pbkdf2

将命令行作为参数代进入, 跟一下openssl命令行工程, 就可以得到C实现(基于openssl API)

简单直白的实现

在查资料过程中, 发现官方测试代码中有一个直白的实现, 自己先弄一个工程试试. 然后再跟官方命令行的实现.
在openssl源码中, 看到了 D:\3rd_prj\crypt\openssl-3.2.0\test\afalgtest.c, 测试了aes-128-cbc, 实现特别简单.

简单直白的实现 - 测试效果

before enc:
0000 - 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f   ................
0010 - 10 11 12 13 14 15 16 17-18 19 1a 1b 1c 1d 1e 1f   ................
0020 - 20 21 22 23 24 25 26 27-28 29 2a 2b 2c 2d 2e 2f    !"#$%&'()*+,-./
0030 - 30 31 32 33 34 35 36 37-38 39 3a 3b 3c 3d 3e 3f   0123456789:;<=>?
0040 - 40 41 42 43 44 45 46 47-48 49 4a 4b 4c 4d 4e 4f   @ABCDEFGHIJKLMNO
0050 - 50 51 52 53 54 55 56 57-58 59 5a 5b 5c 5d 5e 5f   PQRSTUVWXYZ[\]^_
0060 - 60 61 62 63 64 65 66 67-68 69 6a 6b 6c 6d 6e 6f   `abcdefghijklmno
0070 - 70 71 72 73 74 75 76 77-78 79 7a 7b 7c 7d 7e 7f   pqrstuvwxyz{|}~.
0080 - 80 81 82 83 84 85 86 87-88 89 8a 8b 8c 8d 8e 8f   ................
0090 - 90 91 92 93 94 95 96 97-98 99 9a 9b 9c 9d 9e 9f   ................
00a0 - a0 a1 a2 a3 a4 a5 a6 a7-a8 a9 aa ab ac ad ae af   ................
00b0 - b0 b1 b2 b3 b4 b5 b6 b7-b8 b9 ba bb bc bd be bf   ................
00c0 - c0 c1 c2 c3 c4 c5 c6 c7-c8 c9 ca cb cc cd ce cf   ................
00d0 - d0 d1 d2 d3 d4 d5 d6 d7-d8 d9 da db dc dd de df   ................
00e0 - e0 e1 e2 e3 e4 e5 e6 e7-e8 e9 ea eb ec ed ee ef   ................
00f0 - f0 f1 f2 f3 f4 f5 f6 f7-f8 f9 fa fb fc            .............
after enc:
0000 - c6 a1 3b 37 87 8f 5b 82-6f 4f 81 62 a1 c8 d8 79   ..;7..[.oO.b...y
0010 - 35 d9 dc db 82 9f ec 33-52 e7 bf 10 b8 4b e4 a5   5......3R....K..
0020 - 7b 30 46 46 05 f0 2a 09-4c 0a f7 ad 98 4f 61 fc   {0FF..*.L....Oa.
0030 - d8 84 34 a5 59 1d bc 8f-d9 63 08 12 d3 a2 7b 87   ..4.Y....c....{.
0040 - 25 cc 26 ee 46 93 13 40-c1 a9 f1 0d 82 2e aa e3   %.&.F..@........
0050 - 69 f3 ff d0 fc b1 a1 5e-a0 dc d6 c1 75 07 9d 45   i......^....u..E
0060 - 37 d1 e1 58 ec 3d 2f 67-07 de 48 12 5f c4 a4 cb   7..X.=/g..H._...
0070 - 22 62 2b 9d d6 ea 3d 1e-ec c9 c1 5e 53 ea 33 8b   "b+...=....^S.3.
0080 - 92 3a b9 cc 0f cc 8d 8d-da 45 57 a7 09 e5 3e e1   .:.......EW...>.
0090 - 24 0d fb bb 4e 93 18 85-7e 4b 84 2a 9d ae 3c 2d   $...N...~K.*..<-
00a0 - 72 7a 39 39 db 64 24 ed-ba 80 e6 f8 98 d8 35 a7   rz99.d$.......5.
00b0 - 43 13 b6 bd aa ca e7 03-11 e9 97 63 c6 f2 36 7f   C..........c..6.
00c0 - ab 39 b5 fd 1b 4c 34 1f-49 99 b3 06 ff 3e 77 2a   .9...L4.I....>w*
00d0 - df 3f e7 db 00 43 48 99-6f bc b9 43 34 66 50 8e   .?...CH.o..C4fP.
00e0 - f6 0a 2d d3 1a cc 9e d1-36 98 89 40 60 40 3a 48   ..-.....6..@`@:H
00f0 - c6 f1 c5 38 48 65 68 06-b5 df ac ed 84 74 d7 be   ...8Heh......t..
after dec:
0000 - 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f   ................
0010 - 10 11 12 13 14 15 16 17-18 19 1a 1b 1c 1d 1e 1f   ................
0020 - 20 21 22 23 24 25 26 27-28 29 2a 2b 2c 2d 2e 2f    !"#$%&'()*+,-./
0030 - 30 31 32 33 34 35 36 37-38 39 3a 3b 3c 3d 3e 3f   0123456789:;<=>?
0040 - 40 41 42 43 44 45 46 47-48 49 4a 4b 4c 4d 4e 4f   @ABCDEFGHIJKLMNO
0050 - 50 51 52 53 54 55 56 57-58 59 5a 5b 5c 5d 5e 5f   PQRSTUVWXYZ[\]^_
0060 - 60 61 62 63 64 65 66 67-68 69 6a 6b 6c 6d 6e 6f   `abcdefghijklmno
0070 - 70 71 72 73 74 75 76 77-78 79 7a 7b 7c 7d 7e 7f   pqrstuvwxyz{|}~.
0080 - 80 81 82 83 84 85 86 87-88 89 8a 8b 8c 8d 8e 8f   ................
0090 - 90 91 92 93 94 95 96 97-98 99 9a 9b 9c 9d 9e 9f   ................
00a0 - a0 a1 a2 a3 a4 a5 a6 a7-a8 a9 aa ab ac ad ae af   ................
00b0 - b0 b1 b2 b3 b4 b5 b6 b7-b8 b9 ba bb bc bd be bf   ................
00c0 - c0 c1 c2 c3 c4 c5 c6 c7-c8 c9 ca cb cc cd ce cf   ................
00d0 - d0 d1 d2 d3 d4 d5 d6 d7-d8 d9 da db dc dd de df   ................
00e0 - e0 e1 e2 e3 e4 e5 e6 e7-e8 e9 ea eb ec ed ee ef   ................
00f0 - f0 f1 f2 f3 f4 f5 f6 f7-f8 f9 fa fb fc            .............
enc / dec all ok
free map, g_mem_hook_map.size() = 0D:\my_dev\my_local_git_prj\study\openSSL\exp\exp029_enc\aes-128-cbc\prj-aes-128-cbc-simple\x64\Debug\prj-aes-128-cbc-simple.exe (进程 276104)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

简单直白的实现 - 测试工程

/*!
* \file prj-aes-128-cbc-simple
*/#include "my_openSSL_lib.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>#include <stdlib.h>
#include <stdio.h>
#include <assert.h>#include "CMemHookRec.h"#include <openssl/evp.h>void my_openssl_app();bool aes_128_cbc_EncDec(bool isEnc,IN const UCHAR* pszBufIn, IN int lenBufIn, IN const UCHAR* key, IN int lenKey,IN const UCHAR* iv, IN int lenIv,OUT UCHAR*& pOutBuf, OUT int& lenOutBuf);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()
{UCHAR ucBuf[0x100 - 3];int lenBuf = sizeof(ucBuf);int i = 0;UCHAR* pEncBuf = NULL;int lenEncBuf = 0;UCHAR* pDecBuf = NULL;int lenDecBuf = 0;// 可以在EVP_CipherInit_ex()之后, 用EVP_CIPHER_CTX_get_key_length()/EVP_CIPHER_CTX_get_iv_length()看长度UCHAR key[0x10]; // aes-128-cbc's key len = 0x10UCHAR iv[0x10]; // aes-128-cbc's iv len = 0x10for (i = 0; i < 0x10; i++){key[i] = (UCHAR)i;iv[i] = (UCHAR)i;}for (i = 0; i < lenBuf; i++){ucBuf[i] = (UCHAR)i;}do {printf("before enc:\n");BIO_dump_fp(stdout, ucBuf, lenBuf);// enc// // 如果输入不是0x10对齐, 加密后, 就会自动0x10对齐(多出几个字节)// 所以要自己记录加密前的长度, 且加密时, 要将输出(加密后)buffer 16对齐(或直接比输入的长度多16字节)// 且加密后, 要自己记录加密后的长度if (!aes_128_cbc_EncDec(true, ucBuf, lenBuf, (UCHAR*)key, sizeof(key), (UCHAR*)iv, sizeof(iv), pEncBuf, lenEncBuf)){assert(false);break;}// printf("enc before lenBuf = %d, enc after lenEncBuf = %d\n", lenBuf, lenEncBuf);// enc before lenBuf = 253, enc after lenEncBuf = 256printf("after enc:\n");BIO_dump_fp(stdout, pEncBuf, lenEncBuf);// decif (!aes_128_cbc_EncDec(false, pEncBuf, lenEncBuf, (UCHAR*)key, sizeof(key), (UCHAR*)iv, sizeof(iv), pDecBuf, lenDecBuf)){assert(false);break;}// 解密后的数据长度和解密前一样了printf("after dec:\n");BIO_dump_fp(stdout, pDecBuf, lenDecBuf);// 比较明文和解密后的明文是否相同if ((lenDecBuf != lenBuf) || (0 != memcmp(ucBuf, pDecBuf, lenBuf))){assert(false);break;}printf("enc / dec all ok\n");} while (false);if (NULL != pEncBuf){OPENSSL_free(pEncBuf);pEncBuf = NULL;}if (NULL != pDecBuf){OPENSSL_free(pDecBuf);pDecBuf = NULL;}
}bool aes_128_cbc_EncDec(bool isEnc,IN const UCHAR* pszBufIn, IN int lenBufIn,IN const UCHAR* key, IN int lenKey,IN const UCHAR* iv, IN int lenIv,OUT UCHAR*& pOutBuf, OUT int& lenOutBuf)
{bool b_rc = false;int i_rc = 0;int i_tmp = 0;const EVP_CIPHER* _evp_chipher = NULL;EVP_CIPHER_CTX* _evp_cipher_ctx = NULL;do {if ((NULL == pszBufIn) || (lenBufIn <= 0) || (NULL == key) || (lenKey <= 0) ||(NULL == iv) || (lenIv <= 0)){break;}_evp_chipher = EVP_aes_128_cbc();_evp_cipher_ctx = EVP_CIPHER_CTX_new();if (NULL == _evp_cipher_ctx){break;}i_rc = EVP_CipherInit_ex(_evp_cipher_ctx, _evp_chipher, NULL, key, iv, (isEnc ? 1 : 0));if (1 != i_rc){break;}i_tmp = EVP_CIPHER_CTX_get_key_length(_evp_cipher_ctx);if (i_tmp != lenKey){break;}i_tmp = EVP_CIPHER_CTX_get_iv_length(_evp_cipher_ctx);if (i_tmp != lenIv){break;}lenOutBuf = 0;pOutBuf = (UCHAR*)OPENSSL_malloc(lenBufIn + 0x10); // 输出必须比输入大0x10if (NULL == pOutBuf){break;}i_tmp = 0;lenOutBuf = 0;// 如果lenBufIn不是16整除, update 还剩下一个尾巴的数据(len < 0x10)i_rc = EVP_CipherUpdate(_evp_cipher_ctx, pOutBuf, &i_tmp, pszBufIn, lenBufIn);if (1 != i_rc){break;}lenOutBuf += i_tmp;i_tmp = 0;i_rc = EVP_CipherFinal_ex(_evp_cipher_ctx, pOutBuf + lenOutBuf,  &i_tmp);if (1 != i_rc){break;}lenOutBuf += i_tmp;b_rc = true;} while (false);if (NULL != _evp_cipher_ctx){EVP_CIPHER_CTX_free(_evp_cipher_ctx);_evp_cipher_ctx = NULL;}return b_rc;
}

周全灵活的实现

单步openssl 命令行(openssl enc -aes-128-cbc …)的实现, 如果口令给的强度不够, 会加沙.
用BIO链的方式加密, 不用自己分别调用具体的加密API, 用起来简单.

不过, 这个实现的前提是知道上一个简单直白的方法(最直接的调用openssl API), 知道对应算法的key/iv的数据长度
跟了一下官方实现, 没全用.

官方考虑了弱密码的情况, 会根据参数加沙和用pbkdf2(KDF是基于弱密码生成新密码), 然后再用BIO链条完成加密.

我自己用时, 知道每种算法的key, iv长度, 会自己用随机数填满, 就没必要基于KDF来从输入的弱口令生成新的实际加密的密码.

我只用了BIO链的方式加密.
BIO链干活的好处:

  • 算法都是针对BIO链头操作, e.g. 加密时, 只需要向BIO链头写输入数据, 等全部写完(执行BIO_flush(BIO链头)), 只需要再从BIO链头读东西, 就是加密完成的内容. 用起来方便.
  • 如果对输入数据的操作不是一个加密操作, 而是很多操作(e.g. 对称加密, 做hash…), 只需要加入新的BIO节点(通过BIO_push()来控制BIO链中的BIO对象执行顺序), 其他代码不用动, 对于维护友好.

如果只是干一个简单的活(e.g. 针对一块数据加密), 那就用第一种那样直白的方法.

等以后有机会找找官方实现中, 是否有BIO链条大于2个节点的实现, 也继续学习一下.

官方实现中, 是文件到文件的加/解密, 我改成了针对buffer的加/解密.

周全灵活的实现 - 测试效果

before enc:
0000 - 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f   ................
0010 - 10 11 12 13 14 15 16 17-18 19 1a 1b 1c 1d 1e 1f   ................
0020 - 20 21 22 23 24 25 26 27-28 29 2a 2b 2c 2d 2e 2f    !"#$%&'()*+,-./
0030 - 30 31 32 33 34 35 36 37-38 39 3a 3b 3c 3d 3e 3f   0123456789:;<=>?
0040 - 40 41 42 43 44 45 46 47-48 49 4a 4b 4c 4d 4e 4f   @ABCDEFGHIJKLMNO
0050 - 50 51 52 53 54 55 56 57-58 59 5a 5b 5c 5d 5e 5f   PQRSTUVWXYZ[\]^_
0060 - 60 61 62 63 64 65 66 67-68 69 6a 6b 6c 6d 6e 6f   `abcdefghijklmno
0070 - 70 71 72 73 74 75 76 77-78 79 7a 7b 7c 7d 7e 7f   pqrstuvwxyz{|}~.
0080 - 80 81 82 83 84 85 86 87-88 89 8a 8b 8c 8d 8e 8f   ................
0090 - 90 91 92 93 94 95 96 97-98 99 9a 9b 9c 9d 9e 9f   ................
00a0 - a0 a1 a2 a3 a4 a5 a6 a7-a8 a9 aa ab ac ad ae af   ................
00b0 - b0 b1 b2 b3 b4 b5 b6 b7-b8 b9 ba bb bc bd be bf   ................
00c0 - c0 c1 c2 c3 c4 c5 c6 c7-c8 c9 ca cb cc cd ce cf   ................
00d0 - d0 d1 d2 d3 d4 d5 d6 d7-d8 d9 da db dc dd de df   ................
00e0 - e0 e1 e2 e3 e4 e5 e6 e7-e8 e9 ea eb ec ed ee ef   ................
00f0 - f0 f1 f2 f3 f4 f5 f6 f7-f8 f9 fa fb fc            .............
after enc:
0000 - c6 a1 3b 37 87 8f 5b 82-6f 4f 81 62 a1 c8 d8 79   ..;7..[.oO.b...y
0010 - 35 d9 dc db 82 9f ec 33-52 e7 bf 10 b8 4b e4 a5   5......3R....K..
0020 - 7b 30 46 46 05 f0 2a 09-4c 0a f7 ad 98 4f 61 fc   {0FF..*.L....Oa.
0030 - d8 84 34 a5 59 1d bc 8f-d9 63 08 12 d3 a2 7b 87   ..4.Y....c....{.
0040 - 25 cc 26 ee 46 93 13 40-c1 a9 f1 0d 82 2e aa e3   %.&.F..@........
0050 - 69 f3 ff d0 fc b1 a1 5e-a0 dc d6 c1 75 07 9d 45   i......^....u..E
0060 - 37 d1 e1 58 ec 3d 2f 67-07 de 48 12 5f c4 a4 cb   7..X.=/g..H._...
0070 - 22 62 2b 9d d6 ea 3d 1e-ec c9 c1 5e 53 ea 33 8b   "b+...=....^S.3.
0080 - 92 3a b9 cc 0f cc 8d 8d-da 45 57 a7 09 e5 3e e1   .:.......EW...>.
0090 - 24 0d fb bb 4e 93 18 85-7e 4b 84 2a 9d ae 3c 2d   $...N...~K.*..<-
00a0 - 72 7a 39 39 db 64 24 ed-ba 80 e6 f8 98 d8 35 a7   rz99.d$.......5.
00b0 - 43 13 b6 bd aa ca e7 03-11 e9 97 63 c6 f2 36 7f   C..........c..6.
00c0 - ab 39 b5 fd 1b 4c 34 1f-49 99 b3 06 ff 3e 77 2a   .9...L4.I....>w*
00d0 - df 3f e7 db 00 43 48 99-6f bc b9 43 34 66 50 8e   .?...CH.o..C4fP.
00e0 - f6 0a 2d d3 1a cc 9e d1-36 98 89 40 60 40 3a 48   ..-.....6..@`@:H
00f0 - c6 f1 c5 38 48 65 68 06-b5 df ac ed 84 74 d7 be   ...8Heh......t..
after dec:
0000 - 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f   ................
0010 - 10 11 12 13 14 15 16 17-18 19 1a 1b 1c 1d 1e 1f   ................
0020 - 20 21 22 23 24 25 26 27-28 29 2a 2b 2c 2d 2e 2f    !"#$%&'()*+,-./
0030 - 30 31 32 33 34 35 36 37-38 39 3a 3b 3c 3d 3e 3f   0123456789:;<=>?
0040 - 40 41 42 43 44 45 46 47-48 49 4a 4b 4c 4d 4e 4f   @ABCDEFGHIJKLMNO
0050 - 50 51 52 53 54 55 56 57-58 59 5a 5b 5c 5d 5e 5f   PQRSTUVWXYZ[\]^_
0060 - 60 61 62 63 64 65 66 67-68 69 6a 6b 6c 6d 6e 6f   `abcdefghijklmno
0070 - 70 71 72 73 74 75 76 77-78 79 7a 7b 7c 7d 7e 7f   pqrstuvwxyz{|}~.
0080 - 80 81 82 83 84 85 86 87-88 89 8a 8b 8c 8d 8e 8f   ................
0090 - 90 91 92 93 94 95 96 97-98 99 9a 9b 9c 9d 9e 9f   ................
00a0 - a0 a1 a2 a3 a4 a5 a6 a7-a8 a9 aa ab ac ad ae af   ................
00b0 - b0 b1 b2 b3 b4 b5 b6 b7-b8 b9 ba bb bc bd be bf   ................
00c0 - c0 c1 c2 c3 c4 c5 c6 c7-c8 c9 ca cb cc cd ce cf   ................
00d0 - d0 d1 d2 d3 d4 d5 d6 d7-d8 d9 da db dc dd de df   ................
00e0 - e0 e1 e2 e3 e4 e5 e6 e7-e8 e9 ea eb ec ed ee ef   ................
00f0 - f0 f1 f2 f3 f4 f5 f6 f7-f8 f9 fa fb fc            .............
enc / dec all ok
free map, g_mem_hook_map.size() = 0D:\my_dev\my_local_git_prj\study\openSSL\exp\exp029_enc\aes-128-cbc\prj-aes-128-cbc\x64\Debug\prj-aes-128-cbc.exe (进程 413000)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

周全灵活的实现 - 测试工程

/*!
* \file prj-aes-128-cbc.cpp
*/#include "my_openSSL_lib.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>#include <stdlib.h>
#include <stdio.h>
#include <assert.h>#include "CMemHookRec.h"#include <openssl/evp.h>
#include <openssl/bioerr.h>
#include <openssl/err.h>void my_openssl_app();
bool aes_128_cbc_EncDec_v1(bool isEnc,IN const UCHAR* pszBufIn, IN int lenBufIn,IN const UCHAR* key, IN int lenKey,IN const UCHAR* iv, IN int lenIv,OUT UCHAR*& pOutBuf, OUT int& lenOutBuf);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()
{UCHAR ucBuf[0x100 - 3];int lenBuf = sizeof(ucBuf);int i = 0;UCHAR* pEncBuf = NULL;int lenEncBuf = 0;UCHAR* pDecBuf = NULL;int lenDecBuf = 0;// 可以在EVP_CipherInit_ex()之后, 用EVP_CIPHER_CTX_get_key_length()/EVP_CIPHER_CTX_get_iv_length()看长度UCHAR key[0x10]; // aes-128-cbc's key len = 0x10UCHAR iv[0x10]; // aes-128-cbc's iv len = 0x10for (i = 0; i < 0x10; i++){key[i] = (UCHAR)i;iv[i] = (UCHAR)i;}for (i = 0; i < lenBuf; i++){ucBuf[i] = (UCHAR)i;}do {printf("before enc:\n");BIO_dump_fp(stdout, ucBuf, lenBuf);// enc// // 如果输入不是0x10对齐, 加密后, 就会自动0x10对齐(多出几个字节)// 所以要自己记录加密前的长度, 且加密时, 要将输出(加密后)buffer 16对齐(或直接比输入的长度多16字节)// 且加密后, 要自己记录加密后的长度if (!aes_128_cbc_EncDec_v1(true, ucBuf, lenBuf, (UCHAR*)key, sizeof(key), (UCHAR*)iv, sizeof(iv), pEncBuf, lenEncBuf)){assert(false);break;}// printf("enc before lenBuf = %d, enc after lenEncBuf = %d\n", lenBuf, lenEncBuf);// enc before lenBuf = 253, enc after lenEncBuf = 256printf("after enc:\n");BIO_dump_fp(stdout, pEncBuf, lenEncBuf);// decif (!aes_128_cbc_EncDec_v1(false, pEncBuf, lenEncBuf, (UCHAR*)key, sizeof(key), (UCHAR*)iv, sizeof(iv), pDecBuf, lenDecBuf)){assert(false);break;}// 解密后的数据长度和解密前一样了printf("after dec:\n");BIO_dump_fp(stdout, pDecBuf, lenDecBuf);// 比较明文和解密后的明文是否相同if ((lenDecBuf != lenBuf) || (0 != memcmp(ucBuf, pDecBuf, lenBuf))){assert(false);break;}printf("enc / dec all ok\n");} while (false);if (NULL != pEncBuf){OPENSSL_free(pEncBuf);pEncBuf = NULL;}if (NULL != pDecBuf){OPENSSL_free(pDecBuf);pDecBuf = NULL;}
}bool aes_128_cbc_EncDec_v1(bool isEnc,IN const UCHAR* pszBufIn, IN int lenBufIn,IN const UCHAR* key, IN int lenKey,IN const UCHAR* iv, IN int lenIv,OUT UCHAR*& pOutBuf, OUT int& lenOutBuf)
{bool b_rc = false;const EVP_CIPHER* c = NULL;const EVP_MD* dgst = NULL;BIO* bio_in = NULL;BIO* bio_out = NULL;BIO* bio_filter = NULL;int i_tmp = 0;int i_rc = 0;int i_out_len_all = 0;size_t sz_rd = 0;size_t sz_wt = 0;const char* psz = NULL;EVP_CIPHER_CTX* _evp_cipher_ctx = NULL;UCHAR ucBufRd[1024];do {lenOutBuf = 0;if ((NULL == pszBufIn) || (lenBufIn <= 0) ||(NULL == key) || (lenKey <= 0) ||(NULL == iv) || (lenIv <= 0)){break;}c = EVP_aes_128_cbc(); // 这是最初的加密, 没有任何保护的代码, 不用EVP_CIPHER_fetch()来暴露算法名称字符串// 可以从算法对象得到算法名称//psz = EVP_CIPHER_get0_name(c);//printf("EVP_aes_128_cbc()'s alg name is : %s\n", psz);// EVP_aes_128_cbc()'s alg name is : AES-128-CBCi_tmp = EVP_CIPHER_get_key_length(c);if (i_tmp != lenKey){break;}i_tmp = EVP_CIPHER_get_iv_length(c);if (i_tmp != lenIv){break;}dgst = EVP_sha256(); // 这是最初的加密, 没有任何保护的代码, 不用EVP_MD_fetch()来暴露算法名称字符串bio_in = BIO_new_mem_buf(pszBufIn, lenBufIn);if (NULL == bio_in){break;}bio_filter = BIO_new(BIO_f_cipher());// BIO_set_cipher(bio_out, c, key, iv, (isEnc ? 1 : 0));// 由于要改变算法的上下文, 所以要调用BIO_get_cipher_ctx, 而不是调用BIO_set_cipher// 此时 _evp_cipher_ctx 是 NULL// !!! _evp_cipher_ctx 是从bio_filter取出来的, 不能自己新建ctx, 否则向bio_filter写东西时, 就不会加密了, 因为上下文不对BIO_get_cipher_ctx(bio_filter, &_evp_cipher_ctx); // 这里将bio和算法上下文关联了// 此时 _evp_cipher_ctx 不为空, 是bio_filter要用到的算法ctx地址// 向ctx中单独设置加密算法/key/iv// 官方原版实现是分成2步(先设置算法, 再设置key/iv, 有点脱裤子放屁的感觉)if (!EVP_CipherInit_ex(_evp_cipher_ctx, c, NULL, key, iv, (isEnc ? 1 : 0))) {// ERR_print_errors(bio_err);ERR_print_errors_fp(stderr);break;}bio_out = BIO_new(BIO_s_mem());if (NULL == bio_out){break;}// BIO_push返回的就是参数1 bio_out// 释放时, 只需要 BIO_free_all(bio_filter), 不用管bio_out, 因为 bio_out已经加入bio_filter链// !!! 必须向 bio_filter中显势写入从明文bio_in读到的内容, 而不能直接读取bio_filter或者bio_out, 否则报错BIO_push(bio_filter, bio_out); // BIO链, 将明文写入bio_filter, 等全部写完了, 再读biofilter, 就是加密好的密文了// bio_in = BIO_new_mem_buf(pszBufIn, lenBufIn);i_out_len_all = lenBufIn + 0x10; // 加密时, 如果明文长度不是0x10对齐, 那么加密后的长度可能比明文长最多0x10个字节pOutBuf = (UCHAR*)OPENSSL_malloc(i_out_len_all);if (NULL == pOutBuf){break;}lenOutBuf = 0;do {i_rc = BIO_read_ex(bio_in, ucBufRd, sizeof(ucBufRd), &sz_rd);if ((1 != i_rc) || (0 == sz_rd)){// 如果将东西读完了, 也是失败, 这里不错算.i_rc = BIO_flush(bio_filter); // 相当于EVP_CipherFinal_ex()if (1 != i_rc){ERR_print_errors_fp(stderr);goto END;}break;}// 必须向链条的顶部写(write to bio_filter)// 等全部写完(BIO_flush(bio_filter)), 再从链头(bio_filter)读取时, 就已经是加密完的密文了i_rc = BIO_write_ex(bio_filter, ucBufRd, sz_rd, &sz_wt); // 相当于 EVP_CipherUpdate()if (1 != i_rc){ERR_print_errors_fp(stderr);break;}} while (true);lenOutBuf = 0;do {i_rc = BIO_read_ex(bio_out, ucBufRd, sizeof(ucBufRd), &sz_rd);// 这里读最后一块的时候// 加密时, 已经是0x10对齐了// 解密时, 已经是实际的size了if (1 != i_rc){// 如果将东西读完了, 也是失败, 这里不错算.// ERR_print_errors_fp(stderr);break;}memcpy(pOutBuf + lenOutBuf, ucBufRd, sz_rd);lenOutBuf += sz_rd;} while (true);b_rc = true;} while (false);END:if (NULL != bio_in){BIO_free(bio_in);}if (NULL != bio_filter){BIO_free_all(bio_filter); // bio_filter是BIO链, 释放时要用 BIO_free_all()}// 不用释放 _evp_cipher_ctx, 因为 _evp_cipher_ctx属于 bio_filterif (!b_rc){if (NULL != pOutBuf){OPENSSL_free(pOutBuf);pOutBuf = NULL;}}return b_rc;
}

END

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

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

相关文章

【Ubuntu】常用命令

一般操作 pwd&#xff08;present working directory&#xff09; 显示当前的工作目录/路径。 cd (change directory) 改变目录&#xff0c;用于输入需要前往的路径/目录。 有一些特殊命令也很常用 : 解释 前往同一级的另一个目录 cd ../directory name cd .. 表示进入上…

技术周刊 116 期:Visual Copilot、INP、Kimi 支持 200 万字上下文、Grok 开源、Figure 01、Open Sora 开源

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;话梅排骨 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 大家好&#xff0c;我是童欧巴。欢迎来到前端食堂技术周刊&#xff0c;我们先来看下…

STP环路避免实验(华为)

思科设备参考&#xff1a;STP环路避免实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 Spanning Tree Protocol&#xff08;STP&#xff09;&#xff0c;即生成树协议&#xff0c;是一种数据链路层协议。主要作用是防止二层环路&#xff0c;并自适应网络变化和故障…

unity学习(62)——emptyObject+昵称+血条

1.地图比较麻烦&#xff0c;先最后回头再做&#xff0c;地图是锦上添花的东西。 2.MapHandler中的使用技巧&#xff1a; 2.1.继承必须有&#xff0c;要不脚本绑不到相机上 2.2当场景被调用时触发函数OnLevelWasLoaded&#xff0c;这个和Start一样属于一个机制函数。 3.自己做…

长安链Docker Java智能合约引擎的架构、应用与规划

#功能发布 长安链3.0正式版发布了多个重点功能&#xff0c;包括共识算法切换、支持java智能合约引擎、支持后量子密码、web3生态兼容等。我们接下来为大家详细介绍新功能的设计、应用与规划。 在《2022年度长安链开源社区开发者调研报告》中&#xff0c;对Java合约语言支持是开…

分布式幂等性解决方案

分布式幂等性如何设计&#xff1a; 在高并发场景的架构里&#xff0c;幂等性是必须得保证的。比如说支付功能&#xff0c;用户发起支付&#xff0c;如果后台没有做幂等校验&#xff0c;刚好用户手抖多点了几下&#xff0c;于是后台就可能多次受到同一个订单请求&#xff0c;不…

51单片机—直流电机

1.元件介绍 2.驱动电路 3.电机调速 一般会保证一个周期的时间是一样的 应用&#xff1a; 1.LED呼吸灯 #include <REGX52.H>sbit LEDP2^0;void Delay(unsigned int t) {while(t--); } void main() {unsigned char Time,i;while(1){for(Time0;Time<100;Time){for(i0;…

【前端寻宝之路】学习和总结HTML的标签属性

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…

Linux-Arm环境下配置编译qt-everywhere及交叉编译环境

前言 最近在搞交叉编译的事&#xff0c;手上拿了个同事的香橙派玩交叉编译&#xff0c;现在来到了第一步&#xff0c;就是先在arm上配置qt的开发环境。当然了Qt没有直接提供qt on arm&#xff0c;而是需要自行在arm环境下编译一个qt环境出来&#xff0c;所以这里需要使用到qt提…

【Linux】vim详细介绍(四)

文章目录 什么是 vimvim的主要功能&#xff1a;vim的三种模式.viminfo和.vimrc文件 什么是 vim 点击跳转至官网了解更多 Vim是一款功能强大的文本编辑器&#xff0c;适用于各种编程和文本处理任务&#xff0c;最初由Bram Moolenaar开发于1991年。它是Vi编辑器的增强版&#xf…

项目当中 签到功能 +多级缓存+介绍一下点赞功能

签到是怎么做的&#xff1f; 刚开始想用数据库做来着&#xff0c;后来发现用数据库数据量太大&#xff0c;就找解决方案&#xff0c;想到了用bitMap 位图。 bitMap 位图是什么 &#xff1f; 我们采用的是radis 里的bitMap结构 他本质是字符串 最大512mb 是使用01 来存储…

GitHub Copilot+ESP开发实战-串口

上篇文章讲了GitHub Copilot在应用中可能遇到的问题&#xff0c;接下来小启就简单介绍下GitHub Copilot在ESP32开发中C语言实现串口功能&#xff0c;感兴趣的可以看看。 一、向Copilot提问&#xff1a; 1. ESP32用C语言实现串口初始化&#xff1b; 2.配置uart为1&#xff0c…

【Thread 线程】线程的方法与状态

SueWakeup 个人中心&#xff1a;SueWakeup 系列专栏&#xff1a;学习Java 个性签名&#xff1a;保留赤子之心也许是种幸运吧 本文封面由 凯楠&#x1f4f7; 友情赞助播出&#xff01; 目录 一个线程的生命周期 线程终止的原因 线程的方法 Thread 类的静态方法 1. 设置线程…

59、服务攻防——中间件安全CVE复现IISApacheTomcatNginx

文章目录 中间件——IIS漏洞中间件——Nginx漏洞中间件——Apache中间件——Tomcat 中间件&#xff1a;IIS、Apache、Nginx、Tomcat、Docker、Weblogic、JBoss、WebSphere、Jenkinsphp框架&#xff1a;Laravel、Thinkphppythonl框架&#xff1a;Flaskjs框架&#xff1a;jQueryj…

为什么要减少Http的请求以及如何减少Http请求

为什么要减少Http的请求 减少 HTTP 请求的数量是优化网页性能的一个重要策略&#xff0c;原因有以下几点&#xff1a; 1.延迟&#xff1a;每个 HTTP 请求都会有一定的网络延迟。即使数据量很小&#xff0c;请求和响应的往返时间也可能相当长&#xff0c;特别是在网络条件不好…

王道c语言-链表分为两半,逆置后一半,与前一半轮流合并

王道c语言-链表分为两半&#xff0c;逆置后一半&#xff0c;与前一半轮流合并 设线性表 L ( a 1 , a 2 , a 3 , ⋯ , a n − 2 , a n − 1 , a n ) L(a_1,a2,a3,\cdots,a_{n-2},a_{n-1},a_{n}) L(a1​,a2,a3,⋯,an−2​,an−1​,an​) 采用带头结点的单链表保存&#xff0c;…

【Unity】从0到1的横版2d制作笔记-DAY1

写在前面&#xff1a; 感谢旻子提供的Unity2d课程捏&#xff0c;红豆泥阿里嘎多 创建项目 测试Visual Studio的使用 右键选择【create】&#xff0c;右键创建C# Script&#xff0c;待文件创建完毕后双击查看能否正确跳转。 正确跳转的结果是能看见代码中注释标注有&#xff1a;…

mysql - 查询成本 - 优化器

查询成本 我们之前老说MySQL执行一个查询可以有不同的执行方案&#xff0c;它会选择其中成本最低&#xff0c;或者说代价最低的那种方案去真正的执行查询。不过我们之前对成本的描述是非常模糊的&#xff0c;其实在MySQL中一条查询语句的执行成本是由下边这两个方面组成的&…

低代码开发与数据可视化

随着数字化转型的深入发展&#xff0c;软件开发在各行各业中的重要性日益凸显。近年来&#xff0c;低代码开发与数据可视化技术的兴起&#xff0c;为软件开发带来了革命性的变革。本文将深入探讨低代码开发与数据可视化的概念、优势以及应用场景&#xff0c;旨在帮助读者更好地…

分布式搜索引擎elasticsearch专栏二

上一篇的传送门&#xff1a; 分布式搜索引擎elasticsearch专栏一-CSDN博客 这一篇博文主要讲解elasticsearch的数据搜索功能。下面会分别使用DSL和RestClient实现搜索。 1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsea…