C++国密SM2算法加解密的使用

目录

效果

在线校验

代码实现参考

项目

下载


效果

加密字符串:lxw 123abcD 2024-09-01:12:00

加密后信息:042E82EE8ACE2BD56FA71DC6A0C34190627AA365F8EEE6261903BEE327A85EB5E1D6E78F2D79AD6F6DC9E45C0829625DC3165BB78BD897F99044A640F930653747939CF9D5A10C8216F945A55949D8B759FAC93638AD24321017C83331F213C7599802EA216083D6E6C1372C838B9F1AA756B11E8D3BFF6A294C7FCA61

解密后信息:lxw 123abcD 2024-09-01:12:00

在线校验

地址:https://the-x.cn/cryptography/Sm2.aspx

代码实现参考

https://github.com/yaqiangxue/Test_SM2_encrypt_and_decrypt/tree/master

项目

代码

#include "StdAfx.h"

#include <iostream>

#include <string>

#include <cstring>

#include <memory>

#include <openssl/bio.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <iostream>

#include "sm2_cipher_error_codes.h"

#include "sm2_create_key_pair.h"

#include "sm2_encrypt_and_decrypt.h"

using namespace std;

// 将16进制的string字符串,转成16进制的arr

int hexCharStr2unsignedCharStr(char *src, unsigned long lsrc, int flag, unsigned char * out, unsigned long * lout)

{

if((0 == flag && 0 !=lsrc%2) || (0 != flag && 0 !=lsrc%3) ||NULL == src || NULL == out )

{

return 1;//param err

}

int j = 0;//index of out buff

if(0 == flag)

{ //int i;

for (int i=0; i<lsrc; i += 2)

{

int tmp = 0;

int HIGH_HALF_BYTE = 0;

int LOW_HALF_BYTE = 0;

if (src[i]>= 0x30 && src[i]<=0x39)

{

HIGH_HALF_BYTE = src[i] - 0x30;

}

else if (src[i]>= 0x41 && src[i]<=0x46)

{

HIGH_HALF_BYTE = src[i] - 0x37;

}

else if( src[i]>= 0x61 && src[i]<=0x66)

{

HIGH_HALF_BYTE = src[i] - 0x57;

}

else if( src[i] == 0x20)

{

HIGH_HALF_BYTE = 0x00;

}

else

{

return -1;

}

if (src[i+1]>= 0x30 && src[i+1]<=0x39)

{

LOW_HALF_BYTE = src[i+1] - 0x30;

}

else if (src[i+1]>= 0x41 && src[i+1]<=0x46)

{

LOW_HALF_BYTE = src[i+1] - 0x37;

}

else if( src[i+1]>= 0x61 && src[i+1]<=0x66)

{

LOW_HALF_BYTE = src[i+1] - 0x57;

}

else if( src[i+1] == 0x20)

{

LOW_HALF_BYTE = 0x00;

}

else

{

return -1;

}

tmp = (HIGH_HALF_BYTE<<4) + LOW_HALF_BYTE;

out [j] = tmp;

j++;

}

}

else

{ //int i;

for (int i=0; i<lsrc; i += 3)

{

int tmp = 0;

int HIGH_HALF_BYTE = 0;

int LOW_HALF_BYTE = 0;

if ((i+2<= lsrc) && (src[i+2] != flag))

{

return 1;

}

if (src[i]>= 0x30 && src[i]<=0x39 )

{

HIGH_HALF_BYTE = src[i] - 0x30;

}

else if (src[i]>= 0x41 && src[i]<=0x46)

{

HIGH_HALF_BYTE = src[i] - 0x37;

}

else if( src[i]>= 0x61 && src[i]<=0x66)

{

HIGH_HALF_BYTE = src[i] - 0x57;

}

else

{

return -1;

}

if (src[i+1]>= 0x30 && src[i+1]<=0x39)

{

LOW_HALF_BYTE = src[i+1] - 0x30;

}

else if (src[i+1]>= 0x41 && src[i+1]<=0x46)

{

LOW_HALF_BYTE = src[i+1] - 0x37;

}

else if( src[i+1]>= 0x61 && src[i+1]<=0x66)

{

LOW_HALF_BYTE = src[i+1] - 0x57;

}

else

{

return -1;

}

tmp = (HIGH_HALF_BYTE<<4) + LOW_HALF_BYTE;

out [j] = tmp;

j++;

}

}

* lout = j;

return 0;

}

// 将hexarr 转成16进制的字符串 如 0x11 0x22 转了之后是 "1122"

string array2hex(const unsigned char *arr, size_t len)

{

size_t i;

string res;

char tmp[3];

const char *tab = "0123456789ABCDEF";

res.reserve(len * 2 + 1);

for(i = 0; i < len; ++i) {

tmp[0] = tab[arr[i] >> 4];

tmp[1] = tab[arr[i] & 0xf];

tmp[2] = '\0';

res.append(tmp);

}

return res;

}

int main() {

int error_code;

//生成密钥对

/*SM2_KEY_PAIR key_pair;

if ( error_code = sm2_create_key_pair(&key_pair) )

{

printf("Create SM2 key pair failed!\n");

return (-1);

}

std::string pubKeyStr2=array2hex(key_pair.pri_key,32);

std::string priKeyStr2=array2hex(key_pair.pub_key,65);

std::cout<<"pubKeyStr:"<<pubKeyStr2<<std::endl;

std::cout<<"priKeyStr:"<<priKeyStr2<<std::endl;*/

//公钥是加04的。

std::string pubKeyStr = "04FDFB7C93565AB39E1D8178429632EEC914F6A347AE9A0CE9B201FFAEA81A80CC4D81036191209B21CDBAD8A4BCD5C9A776FEDB771D6D2D8DAC0F1E5941C0F63C";

std::string priKeyStr = "832B9C649C63B376DBD1D858C4D1B804CCFF6F7B6B588A9F30A54AF821F80E86";

std::string msg = "lxw 123abcD 2024-09-01:12:00";

std::cout<<"加密字符串:"<<msg<<std::endl<<std::endl;

int msg_len = msg.length();

//私钥

unsigned char pri_key[32] = {0};

unsigned long pri_key_len = 32;

//公钥

unsigned char pub_key[65] = {0};

unsigned long pub_key_len = 65;

unsigned char c1[65], c3[32];

unsigned long c1Len = 65;

unsigned long c3Len = 32;

unsigned char *c2, *plaintext;

int b = hexCharStr2unsignedCharStr((char*)priKeyStr.c_str(), priKeyStr.length(), 0, pri_key, &pri_key_len);

if(b != 0)

{

printf("转换priKeyStr失败\n");

}

b = hexCharStr2unsignedCharStr((char*)pubKeyStr.c_str(), pubKeyStr.length(), 0, pub_key, &pub_key_len);

if(b != 0)

{

printf("转换pubKeyStr失败\n");

}

if ( !(c2 = (unsigned char *)malloc(msg_len)) )

{

printf("Memory allocation failed!\n");

return ALLOCATION_MEMORY_FAIL;

}

//加密

if ( error_code = sm2_encrypt((unsigned char *)msg.c_str(),

msg_len,

pub_key,

c1,

c3,

c2) )

{

printf("Create SM2 ciphertext by using input defined in standard failed!\n");

free(c2);

return error_code;

}

std::string c1str=array2hex(c1,c1Len);

std::string c2str=array2hex(c2,msg_len);

std::string c3str=array2hex(c3,c3Len);

std::string result=c1str+c2str+c3str;

std::cout<<"加密后信息:"<<result<<std::endl<<std::endl;

//解密

if ( !(plaintext = (unsigned char *)malloc(c2str.length())) )

{

printf("Memory allocation failed!\n");

return ALLOCATION_MEMORY_FAIL;

}

if ( error_code = sm2_decrypt(c1,

c3,

c2,

msg_len,

pri_key,

plaintext) )

{

printf("Decrypt SM2 ciphertext by using private key defined in standard failed!\n");

}

std::string plainTextStr((char*)plaintext);

plainTextStr = plainTextStr.substr(0, msg_len);

std::cout<<"解密后信息:"<<plainTextStr<<std::endl;

free(plaintext);

free(c2);

getchar();

return 0;

}

#include "StdAfx.h"
#include <iostream>
#include <string>
#include <cstring>
#include <memory>
#include <openssl/bio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "sm2_cipher_error_codes.h"
#include "sm2_create_key_pair.h"
#include "sm2_encrypt_and_decrypt.h"

using namespace std;


// 将16进制的string字符串,转成16进制的arr
int hexCharStr2unsignedCharStr(char *src, unsigned long lsrc, int flag, unsigned char * out, unsigned long * lout)
{
	if((0 == flag && 0 !=lsrc%2) || (0 != flag && 0 !=lsrc%3) ||NULL == src || NULL == out )
	{
		return 1;//param err
	}

	int j = 0;//index of out buff
	if(0 == flag)
	{	//int i;
		for (int i=0; i<lsrc; i += 2)
		{
			int tmp = 0;
			int HIGH_HALF_BYTE = 0;
			int LOW_HALF_BYTE = 0;
			if (src[i]>= 0x30 && src[i]<=0x39)
			{
				HIGH_HALF_BYTE = src[i] - 0x30;
			}
			else if (src[i]>= 0x41 && src[i]<=0x46)
			{
				HIGH_HALF_BYTE = src[i] - 0x37;
			}
			else if( src[i]>= 0x61 && src[i]<=0x66)
			{
				HIGH_HALF_BYTE = src[i] - 0x57;
			}
			else if( src[i] == 0x20)
			{
				HIGH_HALF_BYTE = 0x00;
			}
			else
			{
				return -1;
			}

			if (src[i+1]>= 0x30 && src[i+1]<=0x39)
			{
				LOW_HALF_BYTE = src[i+1] - 0x30;
			}
			else if (src[i+1]>= 0x41 && src[i+1]<=0x46)
			{
				LOW_HALF_BYTE = src[i+1] - 0x37;
			}
			else if( src[i+1]>= 0x61 && src[i+1]<=0x66)
			{
				LOW_HALF_BYTE = src[i+1] - 0x57;
			}
			else if( src[i+1] == 0x20)
			{
				LOW_HALF_BYTE = 0x00;
			}
			else
			{
				return -1;
			}

			tmp = (HIGH_HALF_BYTE<<4) + LOW_HALF_BYTE;
			out [j] = tmp;
			j++;
		}
	}
	else
	{	//int i;
		for (int i=0; i<lsrc; i += 3)
		{
			int tmp = 0;
			int HIGH_HALF_BYTE = 0;
			int LOW_HALF_BYTE = 0;
			if ((i+2<= lsrc) && (src[i+2] != flag))
			{
				return 1;
			}

			if (src[i]>= 0x30 && src[i]<=0x39 )
			{
				HIGH_HALF_BYTE = src[i] - 0x30;
			}
			else if (src[i]>= 0x41 && src[i]<=0x46)
			{
				HIGH_HALF_BYTE = src[i] - 0x37;
			}
			else if( src[i]>= 0x61 && src[i]<=0x66)
			{
				HIGH_HALF_BYTE = src[i] - 0x57;
			}
			else
			{
				return -1;
			}

			if (src[i+1]>= 0x30 && src[i+1]<=0x39)
			{
				LOW_HALF_BYTE = src[i+1] - 0x30;
			}
			else if (src[i+1]>= 0x41 && src[i+1]<=0x46)
			{
				LOW_HALF_BYTE = src[i+1] - 0x37;
			}
			else if( src[i+1]>= 0x61 && src[i+1]<=0x66)
			{
				LOW_HALF_BYTE = src[i+1] - 0x57;
			}
			else
			{
				return -1;
			}

			tmp = (HIGH_HALF_BYTE<<4) + LOW_HALF_BYTE;
			out [j] = tmp;
			j++;
		}
	}

	* lout = j;
	return 0;

}

// 将hexarr 转成16进制的字符串  如 0x11 0x22  转了之后是 "1122"
string array2hex(const unsigned char *arr, size_t len)
{
	size_t i;
	string res;
	char tmp[3];
	const char *tab = "0123456789ABCDEF";
	res.reserve(len * 2 + 1);
	for(i = 0; i < len; ++i) {
		tmp[0] = tab[arr[i] >> 4];
		tmp[1] = tab[arr[i] & 0xf];
		tmp[2] = '\0';
		res.append(tmp);
	}
	return res;
}

int main() {

	int error_code;
	//生成密钥对
	/*SM2_KEY_PAIR key_pair;
	if ( error_code = sm2_create_key_pair(&key_pair) )
	{
	printf("Create SM2 key pair failed!\n");
	return (-1);
	}
	std::string pubKeyStr2=array2hex(key_pair.pri_key,32);
	std::string priKeyStr2=array2hex(key_pair.pub_key,65);
	std::cout<<"pubKeyStr:"<<pubKeyStr2<<std::endl;
	std::cout<<"priKeyStr:"<<priKeyStr2<<std::endl;*/

	//公钥是加04的。
	std::string pubKeyStr = "04FDFB7C93565AB39E1D8178429632EEC914F6A347AE9A0CE9B201FFAEA81A80CC4D81036191209B21CDBAD8A4BCD5C9A776FEDB771D6D2D8DAC0F1E5941C0F63C";
	std::string priKeyStr = "832B9C649C63B376DBD1D858C4D1B804CCFF6F7B6B588A9F30A54AF821F80E86";

	std::string msg = "lxw 123abcD 2024-09-01:12:00";
	std::cout<<"加密字符串:"<<msg<<std::endl<<std::endl;
	int msg_len = msg.length();

	//私钥
	unsigned char pri_key[32] = {0};
	unsigned long pri_key_len = 32;

	//公钥
	unsigned char pub_key[65] = {0}; 
	unsigned long pub_key_len = 65;

	unsigned char c1[65], c3[32];
	unsigned long c1Len = 65;
	unsigned long c3Len = 32;
	unsigned char *c2, *plaintext;

	int b = hexCharStr2unsignedCharStr((char*)priKeyStr.c_str(), priKeyStr.length(), 0, pri_key, &pri_key_len);
	if(b != 0)
	{
		printf("转换priKeyStr失败\n");
	}

	b = hexCharStr2unsignedCharStr((char*)pubKeyStr.c_str(), pubKeyStr.length(), 0, pub_key, &pub_key_len);
	if(b != 0)
	{
		printf("转换pubKeyStr失败\n");
	}

	if ( !(c2 = (unsigned char *)malloc(msg_len)) )
	{
		printf("Memory allocation failed!\n");
		return ALLOCATION_MEMORY_FAIL;
	}

	//加密
	if ( error_code = sm2_encrypt((unsigned char *)msg.c_str(),
		msg_len,
		pub_key,
		c1,
		c3,
		c2) )
	{
		printf("Create SM2 ciphertext by using input defined in standard failed!\n");
		free(c2);
		return error_code;
	}
	std::string c1str=array2hex(c1,c1Len);
	std::string c2str=array2hex(c2,msg_len);
	std::string c3str=array2hex(c3,c3Len);

	std::string result=c1str+c2str+c3str;
	std::cout<<"加密后信息:"<<result<<std::endl<<std::endl;

	//解密
	if ( !(plaintext = (unsigned char *)malloc(c2str.length())) )
	{
		printf("Memory allocation failed!\n");
		return ALLOCATION_MEMORY_FAIL;
	}
	if ( error_code = sm2_decrypt(c1,
		c3,
		c2,
		msg_len,
		pri_key,
		plaintext) )
	{
		printf("Decrypt SM2 ciphertext by using private key defined in standard failed!\n");
	}

	std::string plainTextStr((char*)plaintext);
	plainTextStr = plainTextStr.substr(0, msg_len);
	std::cout<<"解密后信息:"<<plainTextStr<<std::endl;

	free(plaintext);
	free(c2);

	getchar();
	return 0;
}

下载

源码下载

相关推荐
KeyPan4 分钟前
【视觉惯性SLAM:十一、ORB-SLAM2:跟踪线程】
人工智能·数码相机·算法·机器学习·计算机视觉
吾与谁归in7 分钟前
【C#学习——特性】
开发语言·c#
code monkey.8 分钟前
【探寻C++之旅】第一章:C++入门
开发语言·c++
XiaoLeisj17 分钟前
【递归,搜索与回溯算法 & 记忆化搜索】深入理解记忆化搜索算法:记忆化搜索算法小专题
算法·leetcode·决策树·深度优先·动态规划·剪枝
yava_free27 分钟前
指定Bean加载顺序的能力
java·开发语言
程序员老冯头28 分钟前
第二十三章 C++ 继承
开发语言·数据结构·c++·算法·继承
whisperrr.33 分钟前
探索JDBC:Java数据库连接的艺术与魅力
java·开发语言·数据库
意疏36 分钟前
【机器学习篇】从新手探寻到算法初窥:数据智慧的开启之门
人工智能·算法·机器学习
非凡的世界39 分钟前
使用PHP函数 “setcookie“ 设置cookie
开发语言·php
Dream it possible!1 小时前
LeetCode 热题 100_二叉树的最大深度(37_104_简单_C++)(二叉树;递归;层次遍历)
c++·算法·leetcode