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

news2024/9/23 7:29:19

目录

效果

在线校验

代码实现参考

项目

下载


效果

加密字符串: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.coloradmin.cn/o/2097084.html

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

相关文章

【Python】标准库的使用

文章目录 标准库日期计算字符串操作剑指offer 58&#xff0c;翻转单词顺序思路 leetcode 796&#xff0c;旋转字符串思路 leetcode 2255&#xff0c;统计是给定字符串前缀的字符串数目思路 文件查找工具 Python 通过模块来体现“库” 降低了程序猿的学习成本提高了程序的开发效…

一文带你玩转美国头条NewsBreak平台广告开户优势

一文带你玩转美国头条NewsBreak平台广告开户优势 一、NewsBreak是什么&#xff1a;美国资讯APP的璀璨新星 NewsBreak平台&#xff0c;一款在美国本土迅速崛起的资讯APP&#xff0c;以其1600万的日活跃用户和4000万的新闻订阅用户&#xff0c;成为众多出海企业关注的焦点。它不…

vue-virtual-scroller插件实现不等高表格虚拟滚动

对于大量的表格数据加载&#xff0c;如果我们全部加载不仅面临加载等待时间长&#xff0c;容易崩溃的问题&#xff0c;还有可能导致浏览器缓存数据量大而导致页面使用卡顿的情况。 所以我们使用虚拟滚动加载来优化这种情况&#xff0c;在这里我们使用插件vue-virtual-scroller来…

【Windows】windows powershell 如何实现tail -f xx.log 实时看日志的功能?

windows powershell 如何实现tail -f xx.log 实时看日志的功能&#xff1f; 在Windows PowerShell中&#xff0c;要实现类似于Linux中的tail -f xx.log实时查看日志文件的功能&#xff0c;可以使用Get-Content命令配合-Tail和-Wait参数。这将让你能够实时地查看日志文件的变化。…

前端面试资料集合

整理了前端面试相关资料&#xff0c;包含课程(5们)、面试题(道)、面试书籍(本)&#xff0c;希望对加大有用&#xff0c;欢迎收藏。 面试课程&#xff1a; 1、前端开发技术面试指南及真题讲解带你入坑BAT 这门课程主要针对想要进入BAT&#xff08;百度、阿里巴巴、腾讯&#…

(11)电调和电机

文章目录 前言 1 电机 2 无刷电机ESC 2.1 协议 2.2 使用BLHeli32或BLHeli-S配置固件的ESC 2.3 遥测 3 ESC接线和大型QuadPlane ESC问题 前言 ArduPilot 支持各种 ESC、电机和电子燃油系统。以下页面提供了最流行类型的设置说明。 ArduPilot 支持各种 ESC、电机和电子燃…

[oeasy]python0032_ 火星文字幕_os_操作系统的作用_time_sleep_延迟

火星文字幕_os_操作系统的作用_time_sleep_延迟 &#x1f94b; 回忆上次内容 这次我们了解了unix系统 在multics项目失败后汤普森和里奇 为了 玩游戏自制了 unix 这个世界从此有了 操作系统operating systemos 这个os有什么用吗&#xff1f;&#x1f914; 回忆shell执行…

Qt技巧(二)-滑动界面,轮询控件,循环操作控件

在Qt界面开发过程中&#xff0c;我们常常要对同类部件&#xff0c;具有同样功能的一系列部件进行操作&#xff0c;比如&#xff1a; 这个页面该怎么设计&#xff0c;中间的几个选项该怎么操作&#xff1f; 我们在主工程中添加一个设计师界面类&#xff0c;类名设置为“BrandF…

【pytorch】torch、torchaudio、torchvision版本对应关系

在官网查询版本对应关系 https://pytorch.org/get-started/previous-versions/

【论文阅读】语义通信安全研究综述(2024)

摘要 语义通信系统架构 笔记 内容概述 引言&#xff1a;介绍了语义通信技术的背景、发展和重要性&#xff0c;以及它在无线通信系统中面临的安全挑战。 语义通信系统架构及安全攻击&#xff1a;描述了一个端到端的深度学习语义通信系统的基本架构&#xff0c;包括语义编解码…

会议记录|MAS Lab 年度组会记录

前言&#xff1a;本篇博客记录 20240831 MAS Lab 第一次大组会要点。 “预测未来最好的方式就是创造它” —— 面向对象之父 Alan Kay 张老师提及 The MIT Media Lab &#xff08;中国多媒体大会上了解到的这个实验室&#xff09;&#xff0c;用技术带动产业发展、创造生态。 …

在工作中,这些问题,你是不是已经忍了很久?

在工作中&#xff0c;这些问题&#xff0c;你是不是已经忍了很久&#xff1f;每次找文件像在翻垃圾堆&#xff0c;办公室里纸山堆积得让人喘不过气。关键资料丢失让你夜不能寐&#xff0c;数据出错让你心烦意乱。面对这些反复出现的麻烦&#xff0c;你是否已经感到无比沮丧和焦…

Python 如何创建和使用进度条(tqdm模块)

在处理大规模数据、运行长时间任务或者需要跟踪任务进度的场景中&#xff0c;进度条&#xff08;Progress Bar&#xff09;是非常有用的工具。Python 的 tqdm 模块提供了一种简便的方法来创建和使用进度条&#xff0c;它的名称来源于阿拉伯语词汇“taqaddum”&#xff0c;意思是…

【方法分享】如何使用WinRAR将文件夹里的每个文件压缩

不知道大家是否会遇到这种情况&#xff0c;将文件夹内的多个文件或文件夹压缩成一个个压缩包文件&#xff0c;这种情况除了将文件夹中的文件一个个压缩&#xff0c;还有什么批量操作的方法呢&#xff1f;今天分享使用WinRAR批量压缩文件到每个单独的文件夹的方法。 方法如下&a…

问题-解决方案对-《分析模式》漫谈24

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的第一章有这么一句&#xff1a; It is an important form because it supports the definition of a pattern as "a solution to a problem in context,&…

constexpr关键字

1.const 在c11之前只有const关键字&#xff0c;主要有两个作用&#xff1a;变量只读&#xff0c;修饰常量。 2.constexpr 在c11中新添加了关键字constexpr(作用&#xff1a;用于修饰常量表达式) 常量表达式&#xff1a;由多个常量组成并在编译过程中就能得到计算结果的表达…

React16新手教程记录

文章目录 前言一些前端面试题1. 搭建项目1. 1 cdn1. 2 脚手架 2. 基础用法2.1 表达式和js语句区别&#xff1a;2.2 jsx2.3 循环map2.4 函数式组件2.5 类式组件2.6 类组件点击事件2.6.1 事件回调函数this指向2.6.2 this解决方案2.6.2.1 通过bind2.6.2.2 箭头函数&#xff08;推荐…

MySQL数据库增删查改(基础)CRUD

CRUD 即增加 (Create) 、查询 (Retrieve) 、更新 (Update) 、删除 (Delete) 四个单词的首字母缩写。 1. 新增&#xff08;Create&#xff09; 1.1单行数据&#xff08;全列插入&#xff09; 比如说&#xff1a;创建一张学生表&#xff0c;有姓名&#xff0c;学号。插入两个学…

C++和OpenGL实现3D游戏编程【连载7】——文字和汉字的显示

1、本节实现的内容 上一节我们讨论了纹理在二维平面内不规则图形贴图的相关基础操作,本节我们开始了解游戏里文字以及汉字的显示方法。本节课我们将从基本的ASCII字符显示,拓展到中文字符的显示,最后再讲到纹理字符的显示,并对各种文字显示方法的优缺点和使用场景进行分析…

改进YOLO的群养猪行为识别算法研究及部署(小程序-网站平台-pyqt)

概述 群养猪的运动信息和行为信息与其健康状况息息相关&#xff0c;但人工巡视费时费力&#xff0c;本实验提出采用行为识别算法于群养猪的养殖管理中&#xff0c;识别群养猪drink&#xff08;饮水&#xff09;、stand&#xff08;站立&#xff09;和lie&#xff08;躺卧&#…