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

embedded/2024/11/14 4:05:33/

目录

效果

在线校验

代码实现参考

项目

下载


效果

加密字符串: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.ppmy.cn/embedded/104480.html

相关文章

气膜体育馆:学校体育设施的全新选择—轻空间

随着现代教育的发展&#xff0c;学校对体育设施的需求日益增加。一个良好的体育馆不仅能够为学生提供健康运动的场所&#xff0c;还能为学校举办各类体育赛事、活动提供便利。然而&#xff0c;传统体育馆的建设成本高昂、周期长&#xff0c;并且对场地要求较高。气膜体育馆作为…

关于计算机网络的一个小讨论

采用分组交换方式&#xff0c;将数据包分成较小的包&#xff0c;到达目的地以后再组装起来&#xff0c; 这是路由器功能还是交换机功能 2017年11月26日&#xff0c;星期日&#xff0c;通过描述&#xff0c;可以看出来理论知识实际上还是停留在路由器和交换机上&#xff0c; 分…

MobileNetV2 论文解读

一、介绍 MobileNetv2 网络是由google 团队在2018年提出的&#xff0c;相比MobileNet V1网络&#xff0c;准确率更高&#xff0c;模型更小。 网络中的亮点&#xff1a; Inverted Residuals (倒残差结构) Linear Bottlenecks 二、MobileNetV2详解 2.1 倒残差结构 2.1.1 残差结…

2024年Linux内核社区关于large folio和mthp的关键进展

1. 概述 在 Linux 内核中&#xff0c;一个 folio 可以只包含 1 个 page&#xff0c;也可以包含多个 page。当一个 folio 包含多个 page 的时候&#xff0c;我们称它为一个 large folio&#xff0c;在中文社区&#xff0c;我们一般称呼其为大页。采用 large folio 可潜在带来诸多…

华为OD机试(C卷,100分)- 单词接龙

(C卷,100分)- 单词接龙 题目描述 单词接龙的规则是&#xff1a; 可用于接龙的单词首字母必须要前一个单词的尾字母相同&#xff1b; 当存在多个首字母相同的单词时&#xff0c;取长度最长的单词&#xff0c;如果长度也相等&#xff0c;则取字典序最小的单词&#xff1b;已经参…

NVIDIA Ada Lovelace 架构

目录 3D 图形领域的突破性时刻。 第四代 Tensor Core 第三代 RT Core 着色器执行重排序 DLSS 3 AV1 编码器 致力于打造出色的游戏与创作、专业图形、AI 和计算性能。 3D 图形领域的突破性时刻。 Ada GPU 架构能够为光线追踪和基于 AI 的神经图形提供革命性的性能。该架构…

算法的学习笔记—最小的 K 个数(牛客JZ40)

&#x1f600;前言 在编程面试中&#xff0c;找出一个数组中最小的K个数是一个常见的问题。虽然看似简单&#xff0c;但要在高效性方面有所保证却并不容易。本文将介绍两种有效解决该问题的算法&#xff1a;基于堆的解法和快速选择算法。我们将详细讲解它们的实现方式、时间复杂…

强化学习与深度学习的结合

强化学习与深度学习的结合 目录 一、引言 二、强化学习基础 三、深度学习基础 四、强化学习与深度学习的结合实例 五、总结 一、引言 随着人工智能技术的不断发展&#xff0c;强化学习已经成为了计算机科学领域的一个重要分支。而深度学习作为一种强大的机器学习方…