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

2024-08-28 09:28

本文主要是介绍国密起步1:GmSSL3安装和使用AES,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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


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

目录

一、介绍

二、国密、普密、商密

三、下载和安装

四、AES测试

4.1 不兼容之处

4.2 测试代码

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 secStart 47: sm4_cbc_mac
47/53 Test #47: sm4_cbc_mac ......................   Passed    0.00 secStart 48: sm3_commands
48/53 Test #48: sm3_commands .....................   Passed    0.02 secStart 49: sm2_commands
49/53 Test #49: sm2_commands .....................   Passed    0.17 secStart 50: cert_commands
50/53 Test #50: cert_commands ....................   Passed    0.62 secStart 51: tlcp_commands
51/53 Test #51: tlcp_commands ....................***Exception: Child terminated  7.07 secStart 52: tls12_commands
52/53 Test #52: tls12_commands ...................***Exception: Child terminated  7.11 secStart 53: tls13_commands
53/53 Test #53: tls13_commands ...................***Exception: Child terminated  7.10 sec94% tests passed, 3 tests failed out of 53Total Test time (real) =  25.16 secThe 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 测试代码

//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;}};//由于网上的例子也一样无法解密,所以自行实现CBCstatic 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/32memset((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/32memset((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-linestatic 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 entrypointstatic 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 decryptionunsigned 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-256AES_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/32memset((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 运行结果

[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

这篇关于国密起步1:GmSSL3安装和使用AES的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

mybatis中resultMap的association及collectio的使用详解

《mybatis中resultMap的association及collectio的使用详解》MyBatis的resultMap定义数据库结果到Java对象的映射规则,包含id、type等属性,子元素需... 目录1.reusltmap的说明2.association的使用3.collection的使用4.总

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Java中使用 @Builder 注解的简单示例

《Java中使用@Builder注解的简单示例》@Builder简化构建但存在复杂性,需配合其他注解,导致可变性、抽象类型处理难题,链式编程非最佳实践,适合长期对象,避免与@Data混用,改用@G... 目录一、案例二、不足之处大多数同学使用 @Builder 无非就是为了链式编程,然而 @Builder

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

mybatis-plus QueryWrapper中or,and的使用及说明

《mybatis-plusQueryWrapper中or,and的使用及说明》使用MyBatisPlusQueryWrapper时,因同时添加角色权限固定条件和多字段模糊查询导致数据异常展示,排查发... 目录QueryWrapper中or,and使用列表中还要同时模糊查询多个字段经过排查这就导致只要whe

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo