国密起步1:GmSSL3安装和使用AES

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


此源码位于othertest目录,需要自行编译。(chomd 755 *.sh;rebuild.sh;run.sh

目录

一、介绍

二、国密、普密、商密

三、下载和安装

四、AES测试

[4.1 不兼容之处](#4.1 不兼容之处)

[4.2 测试代码](#4.2 测试代码)

[4.3 运行结果](#4.3 运行结果)


一、介绍

国密库GmSSL的官网:关于GmSSL

官网的简介:

GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法、SM2国密数字证书及基于SM2证书的SSL/TLS安全通信协议,支持国密硬件密码设备,提供符合国密规范的编程接口与命令行工具,可以用于构建PKI/CA、安全通信、数据加密等符合国密标准的安全应用。GmSSL项目是OpenSSL项目的分支,并与OpenSSL保持接口兼容。因此GmSSL可以替代应用中的OpenSSL组件,并使应用自动具备基于国密的安全能力。GmSSL项目采用对商业应用友好的类BSD开源许可证,开源且可以用于闭源的商业应用。

GmSSL项目由北京大学关志副研究员的密码学研究组开发维护,项目源码托管于GitHub。自2014年发布以来,GmSSL已经在多个项目和产品中获得部署与应用,并获得2015年度"一铭杯"中国Linux软件大赛二等奖(年度最高奖项)与开源中国密码类推荐项目。GmSSL项目的核心目标是通过开源的密码技术推动国内网络空间安全建设。

我们不是很关心这些细节,对吧?

二、国密、普密、商密

"国密"有两个意思:国家级秘密和国家密码局。国家级秘密是涉及到国家安全的秘密,普密是党政机关的不涉及国家安全的机密(跟我们一般想的不一样,我们的秘密够不上级别),商密是非国家党政机关的秘密。国家密码局是制定密码标准的国家机关,我们一般说的国密指的是国家密码局制定的商密标准,所以都是以"SM"命名的。

三、下载和安装

直接找到下载,在github下载项目,然后按照说明编译安装,cmake的东西比较简单,一趟就过了,测试最后三个用例没通过(用sudo也不行),不管了,一时半会也用不上高级的。

      Start 46: chacha20
46/53 Test #46: chacha20 .........................   Passed    0.00 sec
      Start 47: sm4_cbc_mac
47/53 Test #47: sm4_cbc_mac ......................   Passed    0.00 sec
      Start 48: sm3_commands
48/53 Test #48: sm3_commands .....................   Passed    0.02 sec
      Start 49: sm2_commands
49/53 Test #49: sm2_commands .....................   Passed    0.17 sec
      Start 50: cert_commands
50/53 Test #50: cert_commands ....................   Passed    0.62 sec
      Start 51: tlcp_commands
51/53 Test #51: tlcp_commands ....................***Exception: Child terminated  7.07 sec
      Start 52: tls12_commands
52/53 Test #52: tls12_commands ...................***Exception: Child terminated  7.11 sec
      Start 53: tls13_commands
53/53 Test #53: tls13_commands ...................***Exception: Child terminated  7.10 sec

94% tests passed, 3 tests failed out of 53

Total Test time (real) =  25.16 sec

The following tests FAILED:
         51 - tlcp_commands (Child terminated)
         52 - tls12_commands (Child terminated)
         53 - tls13_commands (Child terminated)
Errors while running CTest
Makefile:82: recipe for target 'test' failed
make: *** [test] Error 8

install之后得到动态库libgmssl.so和一个目录的头文件(目录名gmssl)。有so和头文件我们就知道该怎么做了。

我装的是最新版,如何查看版本:

user@vm-ubuntu:~/gmssl$ gmssl version
GmSSL 3.1.2 Dev

四、AES测试

AES不是SM系列的算法,但是兼容嘛,所以我们先拿这个来验证。

之前写过OpenSSL的AES测试代码,直接拿过来用,稍微修改一下应该就可以了。

发现不少不同之处啊。

4.1 不兼容之处

  • 头文件目录不同。
  • 库文件名不同。
  • Aes_encrypt函数名和参数顺序不同,此库为aes_encrypt,且参数key为第一个
  • Aes_decrypt类似
  • Rand_bytes函数名不同,此库为rand_bytes
  • Aes_set_encrypt_key函数名和参数不同,此库为aes_set_encrypt_key,且参数为字节长度而不是位长度(不然会coredump啊)
  • AES_set_decrypt_key类似

4.2 测试代码

cpp 复制代码
//myGmSSL.h 文件编码:UTF-8无签名

#pragma once

#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <gmssl/aes.h>
#include <gmssl/rand.h>
#include <vector>
#include "Buffer.h"
#include "mimetype.h"
using namespace std;


namespace ns_my_std
{
	class CMyGmSSL
	{
	private:
		static unsigned char getVer() { return 1; }

		static void show_buf(char const* title, unsigned char const* buf, int len)
		{
			cout << title << " ";
			for (int i = 0; i < len; ++i)
			{
				cout << hex << setw(2) << setfill('0') << (unsigned int)buf[i] << " ";
			}
			cout << endl;
		}
		//需要一个从用户密码生成密钥的函数
	public:
		class IV
		{
		private:
			unsigned char iv[AES_BLOCK_SIZE * 5];
		public:
			IV()
			{
				memset(iv, 0, AES_BLOCK_SIZE * 5);
			}
			//执行异或
			static void XOR(unsigned char const* iv, unsigned char* data)
			{
				//show_buf("IV  ", iv, AES_BLOCK_SIZE);
				//show_buf("DATA", data, AES_BLOCK_SIZE);
				for (int i = 0; i < AES_BLOCK_SIZE; ++i)
				{
					data[i] ^= iv[i];
				}
				//show_buf("DATA", data, AES_BLOCK_SIZE);
			}
			int size()const
			{
				return AES_BLOCK_SIZE;
			}
			//用随机数设置
			void Create()
			{
				time_t t = time(NULL);
				srand(t);
				for (int i = 0; i < AES_BLOCK_SIZE; i += sizeof(int))
				{
					int a = rand();
					memcpy(iv + i, &a, sizeof(int));
				}
			}
			void Set(unsigned char const* a)
			{
				memcpy(iv, a, AES_BLOCK_SIZE);
			}
			//注意,会修改内容
			unsigned char* Get()
			{
				//show_buf("", iv, AES_BLOCK_SIZE * 2);
				return iv;
			}
		};
		//由于网上的例子也一样无法解密,所以自行实现CBC
		static void my_AES_cbc_encrypt(const unsigned char* in, unsigned char* out, size_t length, const AES_KEY* key, unsigned char* ivec, bool isEnc)
		{
			//AES_cbc_encrypt(in, out, length, key, ivec, enc);
			for (int i = 0; i < (int)length; i += AES_BLOCK_SIZE)
			{
				if (isEnc)
				{
					unsigned char tmpin[AES_BLOCK_SIZE];
					memcpy(tmpin, in + i, AES_BLOCK_SIZE);
					IV::XOR(ivec, tmpin); thelog << endi;
					aes_encrypt(key, tmpin, out + i); thelog << endi;
					memcpy(ivec, out + i, AES_BLOCK_SIZE);
				}
				else
				{
					unsigned char tmpiv[AES_BLOCK_SIZE];
					memcpy(tmpiv, in + i, AES_BLOCK_SIZE);
					aes_decrypt(key, in + i, out + i);
					IV::XOR(ivec, out + i);
					memcpy(ivec, tmpiv, AES_BLOCK_SIZE);
				}
			}
		}
		static int my_aes_encrypt(unsigned char const* userpasswd, int userpasswd_len, vector<unsigned char> const& in_plain, vector<unsigned char>& out_ciphertext, IV& iv)
		{
			out_ciphertext.clear();
			unsigned char userkey[32];//必须是16/24/32
			memset((void*)userkey, '\0', 32);
			memcpy(userkey, userpasswd, (userpasswd_len > 32 ? 32 : userpasswd_len));
			/*设置加密key及密钥长度*/
			AES_KEY key;
			if (aes_set_encrypt_key(&key, userkey, 32) < 0)
			{
				return __LINE__;
			}

			int len = 0;
			/*循环加密,每次只能加密AES_BLOCK_SIZE长度的数据*/
			out_ciphertext.reserve(in_plain.size() + AES_BLOCK_SIZE);
			while (len < (int)in_plain.size())
			{
				if (0 == len)
				{//第一个块是明文长度
					out_ciphertext.resize(out_ciphertext.size() + AES_BLOCK_SIZE);
					unsigned char tmp[AES_BLOCK_SIZE];
					memset((void*)tmp, '\0', AES_BLOCK_SIZE);
					uint64_t tmp_len = in_plain.size();
					memcpy(tmp, &tmp_len, sizeof(uint64_t));
					//show_buf("明文长度加密前 ", tmp, AES_BLOCK_SIZE);
					my_AES_cbc_encrypt(tmp, &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), true);
					//show_buf("明文长度加密后", &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE);
				}
				out_ciphertext.resize(out_ciphertext.size() + AES_BLOCK_SIZE);
				if (in_plain.size() - len < AES_BLOCK_SIZE)
				{
					unsigned char tmp[AES_BLOCK_SIZE];
					memset((void*)tmp, '\0', AES_BLOCK_SIZE);
					memcpy(tmp, &in_plain[len], in_plain.size() - len);
					my_AES_cbc_encrypt(tmp, &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), true);
				}
				else
				{
					my_AES_cbc_encrypt(&in_plain[len], &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), true);
				}
				len += AES_BLOCK_SIZE;
			}

			return 0;
		}
		static int my_aes_decrypt(unsigned char const* userpasswd, int userpasswd_len, vector<unsigned char> const& in_ciphertext, vector<unsigned char>& out_plain, IV& iv)
		{
			out_plain.clear();
			unsigned char userkey[32];//必须是16/24/32
			memset((void*)userkey, '\0', 32);
			memcpy(userkey, userpasswd, (userpasswd_len > 32 ? 32 : userpasswd_len));
			/*设置解密key及密钥长度*/
			AES_KEY key;
			if (aes_set_decrypt_key(&key, userkey, 32) < 0)
			{
				return __LINE__;
			}

			int len = 0;
			/*循环解密*/
			out_plain.reserve(in_ciphertext.size());
			uint64_t out_len = 0;//原始长度,放在第一个加密块
			while (len < (int)in_ciphertext.size())
			{
				if (0 == len)
				{//第一个块是明文长度
					unsigned char tmp[AES_BLOCK_SIZE];
					//show_buf("明文长度解密前", &in_ciphertext[len], AES_BLOCK_SIZE);
					my_AES_cbc_encrypt(&in_ciphertext[len], tmp, AES_BLOCK_SIZE, &key, iv.Get(), false);
					//show_buf("明文长度解密后", tmp, AES_BLOCK_SIZE);
					memcpy(&out_len, tmp, sizeof(uint64_t));
					//thelog << "明文长度应该是 " << out_len << endi;
					len += AES_BLOCK_SIZE;
				}
				out_plain.resize(out_plain.size() + AES_BLOCK_SIZE);
				my_AES_cbc_encrypt(&in_ciphertext[len], &out_plain[out_plain.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), false);
				len += AES_BLOCK_SIZE;
			}

			//恢复原始长度
			if ((uint64_t)out_plain.size() > out_len)out_plain.resize(out_len);

			return 0;
		}
		//保护数据,用密码加密并做格式转换
		static bool protect_encode(string const& _passwd, string const& _input, string& _output)
		{
			CUnsignedBuffer passwd;
			CUnsignedBuffer input;
			CUnsignedBuffer output;
			passwd.SetData(_passwd.c_str(), _passwd.size());
			input.SetData(_input.c_str(), _input.size());
			if (protect_encode(passwd, input, output))
			{
				_output = (char *)output.data();
				return true;
			}
			return false;
		}
		static bool protect_encode(CUnsignedBuffer const& passwd, CUnsignedBuffer const& input, CUnsignedBuffer& output)
		{
			output.setSize(0);
			IV iv;
			iv.Create();

			CUnsignedBuffer tmp;
			unsigned char ver = getVer();
			tmp.AddData(&ver, 1);//第一个字节是版本
			tmp.AddData(iv.Get(), iv.size());//然后是IV,必须在加密之前保存,加密之后会改变

			//加密
			vector<unsigned char> in_plain;
			in_plain.resize(input.size());
			memcpy(&in_plain[0], input.data(), input.size());
			vector<unsigned char> out_ciphertext;
			my_aes_encrypt(passwd.data(), passwd.size(), in_plain, out_ciphertext, iv);
			//thelog << out_ciphertext.size() << endi;

			//添加加密后数据
			tmp.AddData(&out_ciphertext[0], out_ciphertext.size());
			//thelog << tmp.size() << endi;

			output.reserve(tmp.size() * 4 / 3 + 4 + 1);//三字节转为4字节,编码函数在最后还会加上一个字符串结束符
			//thelog << output.capacity() << " " << output.size() << endi;
			int n = CBase64::Base64Enc(output.lockBuffer(), tmp.data(), tmp.size());
			output.releaseBuffer();
			if (n > (int)output.capacity())thelog << "长度不足" << ende;
			output.setSize(n);
			//thelog << output.size() << " [" << output.data() << "]" << endi;

			return true;
		}
		//保护数据,用密码加密并做格式转换
		static bool protect_decode(string const& _passwd, string const& _input, string& _output)
		{
			CUnsignedBuffer passwd;
			CUnsignedBuffer input;
			CUnsignedBuffer output;
			passwd.SetData(_passwd.c_str(), _passwd.size());
			input.SetData(_input.c_str(), _input.size());
			if (protect_decode(passwd, input, output))
			{
				_output = (char*)output.data();
				return true;
			}
			return false;
		}
		static bool protect_decode(CUnsignedBuffer const& passwd, CUnsignedBuffer const& input, CUnsignedBuffer& output)
		{
			output.setSize(0);

			CUnsignedBuffer tmp;
			//这里导致了奇怪的内存错误,实际并不需要这么长
			tmp.reserve(input.size() + 100);//实际需要的是4转3,解码函数最后会加上一个字符串结束符
			//thelog << input.size() << " " << tmp.capacity() << " " << tmp.size() << endi;
			int n = CBase64::Base64Dec((char*)tmp.lockBuffer(), (char*)input.data(), input.size());
			tmp.releaseBuffer();
			if (n<0 || n >(int)tmp.capacity())thelog << "长度不足" << ende;
			tmp.setSize(n);

			unsigned char ver = getVer();
			if (tmp.data()[0] != ver)
			{
				thelog << "加密版本错误" << ende;
				return false;
			}
			else
			{
				//thelog << "加密版本 " << (int)tmp.data()[0]<<" " << (int)ver << ende;
			}

			IV iv;
			iv.Set(tmp.data() + 1);

			vector<unsigned char> in_plain;
			in_plain.resize(tmp.size() - 1 - iv.size());
			memcpy(&in_plain[0], tmp.data() + 1 + iv.size(), tmp.size() - 1 - iv.size());
			//thelog << tmp.size() << " " << in_plain.size() << endi;
			vector<unsigned char> out_ciphertext;
			my_aes_decrypt(passwd.data(), passwd.size(), in_plain, out_ciphertext, iv);

			output.AddData(&out_ciphertext[0], out_ciphertext.size());

			return true;
		}
		// a simple hex-print routine. could be modified to print 16 bytes-per-line
		static void hex_print(const void* pv, size_t len)
		{
			const unsigned char* p = (const unsigned char*)pv;
			if (NULL == pv)
			{
				printf("NULL");
			}
			else
			{
				size_t i = 0;
				for (; i < len; ++i)
				{
					printf("%02X ", *p++);
				}
			}
			printf("\n");
		}

		// main entrypoint
		static int a()
		{
			int const keylength = 128;

			/* generate a key with a given length */
			unsigned char aes_key[keylength / 8];
			memset(aes_key, 0, keylength / 8);
			if (!rand_bytes(aes_key, keylength / 8))
			{
				return __LINE__;
			}

			char const* input = "12345678901234567890";
			size_t const inputslength = 32;

			/* generate input with a given length */
			unsigned char aes_input[inputslength];
			memset(aes_input, 0, inputslength);
			memcpy(aes_input, input, strlen(input));

			/* init vector */
			unsigned char iv_enc[AES_BLOCK_SIZE], iv_dec[AES_BLOCK_SIZE];
			rand_bytes(iv_enc, AES_BLOCK_SIZE);
			memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE);

			// buffers for encryption and decryption
			unsigned char enc_out[inputslength];
			unsigned char dec_out[inputslength];
			memset(enc_out, 0, sizeof(enc_out));
			memset(dec_out, 0, sizeof(dec_out));

			// so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256
			AES_KEY enc_key, dec_key;
			aes_set_encrypt_key(&enc_key, aes_key, keylength/8);
			my_AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, true);

			aes_set_decrypt_key(&dec_key, aes_key, keylength/8);
			//本函数是网上代码,但是在linux下一样失败,在win下则导致异常(解密正确但退出时异常),原因是此段代码错误使用了长度参数
			//此函数并不处理padding,所以输出长度和输入长度是相同的,只不过加上了cbc操作而已(正如我自己写的那个替代品)
			//此处原来的输入比需要的长,导致堆栈异常,按理多解密一个无意义的块有什么危害呢?
			my_AES_cbc_encrypt(enc_out, dec_out, inputslength, &dec_key, iv_dec, false);

			printf("original(%d):\t", static_cast<int>(sizeof(aes_input)));
			hex_print(aes_input, sizeof(aes_input));

			printf("encrypt(%d):\t", static_cast<int>(sizeof(enc_out)));
			hex_print(enc_out, sizeof(enc_out));

			printf("decrypt(%d):\t", static_cast<int>(sizeof(dec_out)));
			hex_print(dec_out, sizeof(dec_out));

			return 0;
		}
		static bool aes_test()
		{
			if (true)
			{
				constexpr int keybits = 128;
				thelog << "keybits " << keybits <<" bytes "<< keybits / 8 << endi;
				unsigned char userkey[keybits/8];//必须是16/24/32
				memset((void*)userkey, '\0', keybits / 8);
				memcpy(userkey, "12345", 5);
				AES_KEY key;
				if (aes_set_encrypt_key(&key, userkey, keybits/8) < 0)
				{
					return __LINE__;
				}
				unsigned char iv[AES_BLOCK_SIZE];
				unsigned char data[AES_BLOCK_SIZE];
				memset(data, 1, AES_BLOCK_SIZE);
				unsigned char data2[AES_BLOCK_SIZE];
				memset(data2, 0, AES_BLOCK_SIZE);
				unsigned char data3[AES_BLOCK_SIZE * 3];
				memset(data3, 0, AES_BLOCK_SIZE * 3);

				memset(iv, 0, AES_BLOCK_SIZE);
				show_buf("简单输入 ", data, AES_BLOCK_SIZE);
				show_buf("iv ", iv, AES_BLOCK_SIZE);
				my_AES_cbc_encrypt(data, data2, AES_BLOCK_SIZE, &key, iv, true);
				show_buf("加密后   ", data2, AES_BLOCK_SIZE);
				show_buf("iv ", iv, AES_BLOCK_SIZE);

				if (aes_set_decrypt_key(&key,userkey, keybits/8) < 0)
				{
					return __LINE__;
				}
				memset(iv, 0, AES_BLOCK_SIZE);
				show_buf("解密前   ", data2, AES_BLOCK_SIZE);
				show_buf("iv ", iv, AES_BLOCK_SIZE);
				my_AES_cbc_encrypt(data2, data3, AES_BLOCK_SIZE, &key, iv, false);
				show_buf("简单输出 ", data3, AES_BLOCK_SIZE * 3);
				show_buf("iv ", iv, AES_BLOCK_SIZE);

				a(); thelog << "网上代码测试完成" << endi;
			}
			if (true)
			{
				string passwd = "13579";
				vector<unsigned char> plaintext;
				for (int i = 0; i < 65; ++i)
				{
					plaintext.push_back(i);
				}
				vector<unsigned char> out;
				IV iv;
				iv.Create();
				IV iv2;
				iv2.Set(iv.Get());
				//show_buf("初始IV", iv.Get(), iv.size());
				my_aes_encrypt((unsigned char*)passwd.c_str(), passwd.size(), plaintext, out, iv);
				vector<unsigned char> plaintext2;
				//show_buf("初始IV", iv2.Get(), iv2.size());
				my_aes_decrypt((unsigned char*)passwd.c_str(), passwd.size(), out, plaintext2, iv2);

				thelog << plaintext.size() << " " << out.size() << " " << plaintext2.size() << ENDI;
				printf("plantext2: \n");
				for (int i = 0; i < (int)plaintext2.size(); i++)
				{
					printf("%.2x ", plaintext2[i]);
					if ((i + 1) % 32 == 0)
					{
						printf("\n");
					}
				}
				printf("\n");
			}

			if (true)
			{
				try
				{
					char const* plaintext = "1234567890";
					CUnsignedBuffer pass;
					CUnsignedBuffer in;
					CUnsignedBuffer out;
					pass.SetData("123");
					in.SetData(plaintext);
					thelog << in.data() << endi;
					protect_encode(pass, in, out);
					thelog << out.size() << " [" << out.data() << "]" << endi;
					CUnsignedBuffer out2;
					if (!protect_decode(pass, out, out2))thelog << "解码失败" << ende;
					thelog << out2.data() << endi;
					if (0 == strcmp(plaintext, (char*)out2.data()))
					{
						thelog << "匹配成功" << endi;
					}
					else
					{
						thelog << "匹配失败" << ende;
					}
					//out2.lockBuffer();
					//out2.setSize(10240);
				}
				catch (...)
				{
					thelog << "异常发生" << ende;
				}
			}

			return true;
		}
	};
}

4.3 运行结果

cpp 复制代码
[08-26 12:31:18][应用][信息][CommandSet.h            : 236(doCommandSet)][  0.00]
命令表
命令 组           名称      命令 说明
---- ------------ --------- ---- --------
a    未命名命令组 TestGmSSL a    国密测试
---- ------------ --------- ---- --------


请选择命令:(--group选择命令组 b=break)(q=exit default=a):

[08-26 12:31:19][应用][信息] 用户输入的是:a
[08-26 12:31:19][应用][信息][myGmSSL.h               : 373(aes_test)][  0.00]keybits 128 bytes 16
简单输入  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
iv  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
加密后    ee a2 aa 8d 92 fd 10 be 22 03 fe 08 52 6a 57 d1
iv  ee a2 aa 8d 92 fd 10 be 22 03 fe 08 52 6a 57 d1
解密前    ee a2 aa 8d 92 fd 10 be 22 03 fe 08 52 6a 57 d1
iv  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
简单输出  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
iv  ee a2 aa 8d 92 fd 10 be 22 03 fe 08 52 6a 57 d1
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
original(32):   31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 00 00 00 00 00 00 00 00 00 00 00 00
encrypt(32):    7D 36 62 28 9A C8 3B 22 1B CC B8 B7 79 13 CA C4 C9 26 43 A6 D3 23 17 02 7A 93 30 A3 34 63 1A 84
decrypt(32):    31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 00 00 00 00 00 00 00 00 00 00 00 00
[08-26 12:31:19][应用][信息][myGmSSL.h               : 408(aes_test)][  0.00]网上代码测试完成
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               : 429(aes_test)][  0.00]65 96 65
plantext2:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40
[08-26 12:31:19][应用][信息][myGmSSL.h               : 452(aes_test)][  0.00]1234567890
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  95(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               :  96(my_AES_cbc_encrypt)][  0.00]
[08-26 12:31:19][应用][信息][myGmSSL.h               : 454(aes_test)][  0.00]68 [AVPRQGy8Aj5Dlmc7LhtTAgNr4B6769ZxXBhK9K09zWkvHawenVr5/pDgHINXiD8lHA==]
[08-26 12:31:19][应用][信息][myGmSSL.h               : 457(aes_test)][  0.00]1234567890
[08-26 12:31:19][应用][信息][myGmSSL.h               : 460(aes_test)][  0.00]匹配成功
[08-26 12:31:19][应用][信息][CommandSet.h            : 129(doCommand)][  0.00]
命令 TestGmSSL 执行完毕 返回码 0
相关推荐
染指111035 分钟前
50.第二阶段x86游戏实战2-lua获取本地寻路,跨地图寻路和获取当前地图id
c++·windows·lua·游戏安全·反游戏外挂·游戏逆向·luastudio
Code out the future1 小时前
【C++——临时对象,const T&】
开发语言·c++
sam-zy1 小时前
MFC用List Control 和Picture控件实现界面切换效果
c++·mfc
aaasssdddd962 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
发呆小天才O.oᯅ2 小时前
YOLOv8目标检测——详细记录使用OpenCV的DNN模块进行推理部署C++实现
c++·图像处理·人工智能·opencv·yolo·目标检测·dnn
qincjun2 小时前
文件I/O操作:C++
开发语言·c++
星语心愿.2 小时前
D4——贪心练习
c++·算法·贪心算法
汉克老师3 小时前
2023年厦门市第30届小学生C++信息学竞赛复赛上机操作题(三、2023C. 太空旅行(travel))
开发语言·c++
single5943 小时前
【c++笔试强训】(第四十一篇)
java·c++·算法·深度优先·图论·牛客
yuanbenshidiaos3 小时前
C++-----函数与库
开发语言·c++·算法