当前位置: 首页 > article >正文

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;
}

下载

源码下载


http://www.kler.cn/a/286663.html

相关文章:

  • SpringBoot3+Vue3开发学生选课管理系统
  • VSCode下EIDE插件开发STM32
  • 数据库SQLite和SCADA DIAView应用教程
  • 检测到联想鼠标自动调出运行窗口,鼠标自己作为键盘操作
  • CASAIM与友达光电达成深度合作,CASAIM IS自动化蓝光测量技术为创新显示技术发展注入新的活力
  • 科普篇 | “机架、塔式、刀片”三类服务器对比
  • vue3+elementplus的表格展示和分页实战
  • Oracle超详细(数据库编程)
  • vim 简易配置
  • 一键解决LBP2900通信错误的问题(同样支持Win 11系统)
  • 计算机毕业设计选题-基于python的OA办公管理系统【python-爬虫-大数据定制】
  • kubernetes培训
  • 深入探讨Java JSON解析与HTML标签清除:详解与实例
  • Vue3入门 - 解决pinia判断用户是否登录相关错误
  • 【系统架构设计】嵌入式系统设计(1)
  • sql靶场笔记
  • vue3监听键盘长按
  • flutter之image_picker上传图片
  • 小琳Python课堂:Python优先级队列深入解析:`PriorityQueue`类的使用与原理
  • 访问win10共享文件夹:用户或密码不正确 以及 未授予用户在此计算机上的请求登录类型
  • 数据库课程设计:MySQL的应用与实践
  • Vue 3 Composition API 中如何正确添加表单项副本到数组
  • Spring Cloud Alibaba 快速学习之 Gateway
  • Vue59 github案例 vue-resource版本
  • Linux——nginx 负载均衡
  • 用Python实现时间序列模型实战——Day 3: 时间序列数据预处理