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 buffif(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.rhkb.cn/news/414646.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SQL】Delete使用

目录 语法 需求 示例 分析 代码 语法 DELETE删除表中所需内容 删除表中满足特点条件的行&#xff1a;DELETE FROM 表名 WHERE 条件; 删除表中所有行&#xff1a;DELETE FROM 表名; WHERE子句 WHERE子句用于指定从表中选取记录的条件。允许筛选数据&#xff0c;只返回满足…

filezilla使用教程(window下filezilla使用教程)

filezilla使用教程&#xff08;window下filezilla使用教程&#xff09; 一、安装与配置 首先&#xff0c;你需要从FileZilla的官方网站下载并安装适合你操作系统的版本。安装完成后&#xff0c;打开FileZilla&#xff0c;你将看到一个简洁的用户界面。 在FileZilla中&#x…

「SpEL Validator」使用指南(一套无敌的参数校验组件)

前言 这是一套全新的参数校验组件&#xff0c;并非造轮子。 看完本文你可能会觉得用不上或不屑于使用&#xff0c;但这玩意确实有应用场景&#xff0c;你不妨稍微留意一下&#xff0c;日后你总会发现有用得上的时候。 此乃系列文章&#xff0c;当前为第②篇&#xff0c;其他…

用Python实现时间序列模型实战——Day 8: 季节性ARIMA模型 (SARIMA)

一、学习内容 1. SARIMA 模型的定义与公式推导 SARIMA 模型&#xff1a; SARIMA 模型是扩展了 ARIMA 模型的一种方法&#xff0c;全称为季节性自回归积分滑动平均模型&#xff08;Seasonal AutoRegressive Integrated Moving Average&#xff09;。它结合了 ARIMA 模型的非季…

sed awk 第二版学习(二)—— 正则表达式语法

目录 一、表达式 二、成行的字符 1. 反斜杠 2. 通配符 3. 编写正则表达式 4. 字符类 &#xff08;1&#xff09;字符的范围 &#xff08;2&#xff09;排除字符类 &#xff08;3&#xff09;POSIX 字符类补充 5. 重复出现的字符 6. 匹配单词 7. gres 替换脚本 8. …

超越卷积滤波器,HyCoT利用Transformer捕捉高光谱图像的全局依赖性 !

近年来&#xff0c;基于学习的高光谱图像&#xff08;HSI&#xff09;压缩模型的开发引起了大量关注。现有的模型主要使用卷积滤波器&#xff0c;仅捕捉局部依赖性。 此外&#xff0c;它们通常会带来高昂的训练成本&#xff0c;并具有较大的计算复杂性。 为了解决这些问题&…

upload-labs通关攻略

Pass-1 这里上传php文件说不允许上传 然后咱们开启抓包将png文件改为php文件 放包回去成功上传 Pass-2 进来查看提示说对mime进行检查 抓包把这里改为image/jpg; 放包回去就上传成功了 Pass-3 这里上传php文件它说不允许上传这些后缀的文件 那咱们就可以改它的后缀名来绕过…

KinectFusion

1.KinectFusion 笔记来源&#xff1a; 论文地址&#xff1a;KinectFusion: Real-time 3D Reconstruction and Interaction Using a Moving Depth Camera* 项目地址&#xff1a;github/KinectFusion [1] 截断符号距离 | TSDF, Truncated Signed Distance Function 本篇对Kinec…

工业储能柜内部运行状态监测装置

工商业储能是用户侧储能的主要应用之一&#xff0c;其核心场景包括峰谷套利、需&#xff08;容&#xff09;量管理、应急备电、动态增容和需求侧响应。为了实现这些功能并确保储能系统的安全、可靠与经济运行&#xff0c;储能集成厂家必须关注多个方面&#xff0c;其中储能设备…

WPF ToolkitMVVM IOC IServiceConllection

用微软自带的 IOC 需要安装 using Microsoft.Extensions.DependencyInjection; using System.Configuration; using System.Data; using System.Windows;namespace WpfApp3 {/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class…

BITCN合集(BITCN 、BITCN-GRU、BITCN-BIGRU、BITCN-LSTM、BITCN-BILSTM、BITCN-SVM)

BITCN合集&#xff08;BITCN 、BITCN-GRU、BITCN-BIGRU、BITCN-LSTM、BITCN-BILSTM、BITCN-SVM&#xff09; BITCN合集&#xff08;BITCN 、BITCN-GRU、BITCN-BIGRU、BITCN-LSTM等&#xff09;代码获取戳此处代码获取戳此处代码获取戳此处 BITCN&#xff08;双向时间卷积神经网…

uniapp引入最新版Animate.css及使用示例

亲测可用,不好用请移至评论区揍我 动画库官网:https://animate.style/ cdn地址:https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css(截至目前最新版为:v4.1.1) 1. 将css下载后导入项目static目录中 2. 重要!修改下载的css文件内容 文件内容如…

vue脚手架路由快速入门

这里写目录标题 路由 router路由插件的引用离线在线CDN 单独路由使用案例项目中如何定义路由1\安装路由2\创建路由文件router.js以及创建相关文件3\应用插件main.js4\实现切换<router-link></router-link>5\展示位置 <router-view></router-view> 嵌套…

在线绘制哑铃图(dumbbell chart)展示基因拷贝数变异(CNV)

导读&#xff1a; 哑铃图的名称来源于其形状&#xff0c;它看起来像一个哑铃&#xff0c;有两个圆形的“重量”在两端&#xff0c;通过一根“杆”连接。常用于展示两个或多个数据集之间的差异。本文介绍了如何使用哑铃图展示基因的拷贝数变异。 Journal of Translational Medi…

UDP简单聊天室创建

目录 一. 服务端模块实现 二. 处理聊天消息模块实现 三. 调用服务端模块实现 四. 客户端模块实现 五. 效果展示 本文介绍了如何用UDP创建一个简单的聊天室。 一. 服务端模块实现 服务端仍然沿用我们前面的思想&#xff08;高内聚低耦合&#xff09;&#xf…

C语言小tip之函数递归

hello&#xff0c;各位小伙伴们今天我们来学习一下函数递归。 什么是函数递归呢&#xff1f;简单来说就是函数自己来调用自己。函数递归的主要思想是把大事化小&#xff0c;递归包含两层方面&#xff1a;1、递推 2、回归 在使用函数递归的时候要注意包含两个限制条件&#…

Linux 软硬连接

1. 硬链接 实际上并不是通过文件名来找到磁盘上的文件&#xff0c;而是通过inode。在linux中可以让多个文件名对应于同一个 inode&#xff0c;而这种方式就是建立硬链接。硬链接是文件系统中的一种链接类型&#xff0c;它创建了文件的一个额外的目录项&#xff0c;但不占用额外…

全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用

SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型&#xff0c;它综合考虑了土壤-水分-大气以及植被间的相互作用&#xff1b;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程&#xff0c;使其能够精确的模拟土壤中水分的运动&#xff0c;而且耦合了W…

EmguCV学习笔记 C# 7.1 角点检测

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

Ubuntu22.04安装 docker和docker-compose环境

Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;它使开发者能够打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口&#xff08;…