经典SM2密文转 ASN1/DER编码格式

最近在国四协议转发国家平台的事宜。新协议要求国四报文要以加密形式转发给国家平台。可以是国密4,国密2.如果使用国密2的时候,注意密文要使用ASN1/DER编码格式。于是我参考了以下几个链接的内容:

基于OpenSSL,实现SM2密文数据的ASN1编码转换_sm2密钥转asn-CSDN博客

如何实现“使用OpenSSL库进行ASN.1 DER编码的C/C++教程”的具体操作步骤_mob649e815c3b9e的技术博客_51CTO博客

关于SM2算法 ASN.1 DER编码_sm2 der编码密文-CSDN博客

写了我的版本,当然我已经编译过了openssl1.1.1d ,并准备好了inlcude 和lib.

下面是我的代码:


#include <string>
#include <iostream>
#include <openssl/asn1.h>
#include <openssl/ec.h>
#include <openssl/asn1t.h>
using namespace std;// 自定义ASN1编码结构
typedef struct SM2_Ciphertext_st MY_ASN;
DECLARE_ASN1_FUNCTIONS(MY_ASN)typedef struct SM2_Ciphertext_st
{// ASN1_INTEGER *xc;  // x分量// ASN1_INTEGER *yc;  // y分量BIGNUM *xc;  // x分量BIGNUM *yc;  // y分量ASN1_OCTET_STRING *hash; // 杂凑值ASN1_OCTET_STRING *cipherText;
};ASN1_SEQUENCE(MY_ASN) = {ASN1_SIMPLE(MY_ASN, xc, BIGNUM),ASN1_SIMPLE(MY_ASN, yc, BIGNUM),ASN1_SIMPLE(MY_ASN, hash, ASN1_OCTET_STRING),ASN1_SIMPLE(MY_ASN, cipherText, ASN1_OCTET_STRING),
} ASN1_SEQUENCE_END(MY_ASN)// 由OpenSSL提供的宏,实现自定义的ASN1编码
// 调用此宏,便定义了函数: SM2_Ciphertext_new、SM2_Ciphertext_free、d2i_SM2_Ciphertext、i2d_SM2_Ciphertext
IMPLEMENT_ASN1_FUNCTIONS(MY_ASN)#define ERR_HEX2BYTE_PARAM_ERROR			13
#define ERR_HEX2BYTE_INVALID_DATA			14
#define ERR_HEX2BYTE_BEYOND_RANGE			15/*** @brief change a string of Ascii(0--f) to BYTE str* Eg:"1A2B3C4D" (length of 8) will be trasform to byte string 0x1A2B3C4D  (length will be 4)* to use it : hexCharStr2unsignedCharStr("1A2B3C4D", strlen("1A2B3C4D"), 0 , buff, &ulBuffLen);* @param src [in] source string* @param lsrc [in] source string lenth* @param flag [in] just input 0* @param out [out] output BYTE str* @param lout [out] output BYTE str lenth* @return int , 0 -- ok; other : failed*/
int hexCharStr2unsignedCharStr(const 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 ERR_HEX2BYTE_PARAM_ERROR;//param err}unsigned int j = 0;//index of out buffif (0 == flag){for (unsigned 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 ERR_HEX2BYTE_INVALID_DATA;}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 ERR_HEX2BYTE_INVALID_DATA;}tmp = (HIGH_HALF_BYTE << 4) + LOW_HALF_BYTE;out[j] = tmp;j++;}}*lout = j;return 0;
}int main()
{string strX = "3174E0481D4989440BD75EB76AB375F097E86DD0BF3C743B28791105C144C4C9";string strY = "03D42AD3EF928B270DD7DCBD3A464F6EBA15AE2367D050140A35BEA8D7D5A2CD";string strC = "00E848179472475224BFE6E4A11A19BCA3E9576DCF1286EAD62457A74C5A73F8";string strText = "3906F12ECD6274B2575583886751E6E5BD6C48C041359B6BDABF34D796A6675736B076C3BA66FAF542817333A666DFF9F571AC55FFEE12582E16663FF8B55B39F350C15949A4189F5482164DAB15E5E4AC5F4A0A297E838A715A4A8E910EF6D65A49314F80FE5D2117B2BE1342944CD8845B95D9";unsigned char arrX[32] = {0x00}; unsigned long  xlen = 0;unsigned char arrY[32] = {0x00}; unsigned long  ylen = 0;unsigned char arrC[32] = {0x00}; unsigned long  Clen = 0;unsigned char arrText[1024] = {0x00}; unsigned long textlen =0;hexCharStr2unsignedCharStr(strX.c_str(), strX.length(), 0, arrX, &xlen);hexCharStr2unsignedCharStr(strY.c_str(), strY.length(), 0, arrY, &ylen);hexCharStr2unsignedCharStr(strC.c_str(), strC.length(), 0, arrC, &Clen);hexCharStr2unsignedCharStr(strText.c_str(), strText.length(), 0, arrText, &textlen);MY_ASN *pObj = MY_ASN_new();// ASN1_INTEGER *integer1 = ASN1_INTEGER_new();// ASN1_INTEGER *integer2 = ASN1_INTEGER_new();BIGNUM* x; BIGNUM* y;x = y = NULL;x = BN_bin2bn(arrX,32,NULL);y = BN_bin2bn(arrY,32,NULL);ASN1_OCTET_STRING* phash= ASN1_OCTET_STRING_new();ASN1_OCTET_STRING* pCipterTest = ASN1_OCTET_STRING_new();// 分配内存pObj->xc = x;pObj->yc = y;pObj->hash = phash;pObj->cipherText = pCipterTest;ASN1_OCTET_STRING_set(pObj->hash, arrC, 32);ASN1_OCTET_STRING_set(pObj->cipherText, arrText, textlen);// 进行ASN.1 DER编码unsigned char derData[1024];unsigned char *pder = &derData[0];int derDataLength = i2d_MY_ASN(pObj, &(pder));// ASN1_INTEGER_free(pObj->xc);// ASN1_INTEGER_free(pObj->yc);printf("1\n");//ASN1_OCTET_STRING_free(pObj->hash);//ASN1_OCTET_STRING_free(pObj->cipherText);MY_ASN_free(pObj);// 打印printf("DER component:\n");for (int i = 0; i < derDataLength; i++){printf("%02X", derData[i]);}printf("\n\n");return 0;
}

下面是我的一个makefile

############################################################
## makefile of ASN1/DER 验证程序
############################################################
.SUFFIXES: .cppSOURCES  =  main.cpp PROGRAM  = testASN1_Der
CLIB     = SPECIAL_MACRO_FLAGS = -DRELEASE
SPECIAL_CCFLAGS = 
#注意这里的 kafka库用的是特殊的版本,而且单独指定了openssl的库-国密2用
SPECIAL_INCL_PATH  = -I../include  -I../dblibs/openssl_1.1.1d/include
#链接库
SPECIAL_LIB_PATH =  -L../dblibs/openssl_1.1.1d/lib 
SPECIAL_LIB_PATH += -L/usr/lib64  
SPECIAL_LIB_PATH += -L/usr/local/lib64/SPECIAL_LIBS = -lrt -lz -lssl -lcrypto #include ../makefile.include
DBLIBS_HOME=../dblibs
SYS_INCL_PATH = -I/usr/include
INCL_PATH = \${SYS_INCL_PATH} \${SPECIAL_INCL_PATH} \-I.SYS_LIB_PATH  = -L/usr/local/libLIB_PATH += ${SPECIAL_LIB_PATH} ${SYS_LIB_PATH}SYS_LIBS =  -ldl -lpthreadLIBS = ${SPECIAL_LIBS} ${SYS_LIBS} MACRO_FLAGS = ${SPECIAL_MACRO_FLAGS} -D_USE_MACRO -D_DEBUG -D_USE_SECONDCCC=g++
# 编译基础库 - 注意使用了c++11
CCFLAGS  = -std=c++11 -g -Wall -c -fPIC -ggdb3 -Wno-deprecated ${MACRO_FLAGS} ${INCL_PATH} ${SPECIAL_CCFLAGS} LFLAGS = -shared -Wl,-soname,$(SONAME)#因为用到了openssl de libcrypto库又不能改生产环境的状态,就这么搞了
LD_RUN_PATH = -Wl,-rpath=../libc++
# Platform-specific overrides
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
ifeq ($(uname_S),Darwin)SYS_LIBS+=-liconvMACRO_FLAGS +=-D_MAC_OS -D_UNIXLFLAGS = -shared -Wl,-install_name,$(DYLIB_MINOR_NAME)
endifLFLIBS = $(LIB_PATH) $(LIBS)CPPFLAGS = -g ${LIB_PATH} ${SPECIAL_CCFLAGS} CPPLIBS  = ${LIBS}AR       = ar
ARFLAGS  = -ruv
RANLIB	 = ranlibINSTALL_BIN_PATH= ${MTRANS_PRJ_HOME}/bin
TARGET_PATH= ./OBJECTS=${SOURCES:%.cpp=%.o}all: ${CLIB} ${PROGRAM} ${SONAME}${CLIB}: ${OBJECTS}@if [ ! -d ${TARGET_PATH} ]; then mkdir -p ${TARGET_PATH}; fi$(AR) ${ARFLAGS} $@ $(OBJECTS)$(RANLIB) $@${SONAME} : ${OBJECTS}@if [ ! -d ${TARGET_PATH} ]; then mkdir -p ${TARGET_PATH}; fi$(CCC) $(LFLAGS) -o $(SONAME) $(OBJECTS) $(LFLIBS)${PROGRAM}: ${OBJECTS}@if [ ! -d ${TARGET_PATH} ]; then mkdir -p ${TARGET_PATH}; fi$(CCC) $(LD_RUN_PATH) -o $@ ${CPPFLAGS} $(OBJECTS) $(CPPLIBS).cpp.o:$(CCC) $(CCFLAGS) -o $@ -c $< install:@if [ "x${SONAME}" != "x" ]; then echo ${SONAME} ; rm -f "${MTRANS_PRJ_HOME}/libs/lib/${SONAME}"; cp -r ${SONAME} ${MTRANS_PRJ_HOME}/libs/lib; fi	@if [ "x${LNNAME}" != "x" ]; then cd "${MTRANS_PRJ_HOME}/libs/lib"; rm -rf ${LNNAME}; ln -s ${SONAME} ${LNNAME}; fi@if [ "x${PROGRAM}" != "x" ]; then mkdir -p ${INSTALL_BIN_PATH}; cp $(PROGRAM) $(INSTALL_BIN_PATH); fisetup:@if [ "x${PROGRAM}" != "x" ]; then cp $(PROGRAM) /usr/local/lbs/bin/; fi
clean:rm -rf ${OBJECTS} ${CLIB} ${PROGRAM} ${SONAME}
#	rm -rf ir.outrm -rf core.* rm -rf *.o nohup.out@if [ "x${SONAME}" != "x" ]; then rm -rf *.so* ; rm -rf ${MTRANS_PRJ_HOME}/libs/lib/${SONAME}; fi @if [ "x${PROGRAM}" != "x" ]; then rm -rf ${MTRANS_PRJ_HOME}/lbs/log/${PROGRAM}.*; filog:	@rm -f core.* nohup.out valg.log.*@rm -f ${MTRANS_PRJ_HOME}/lbs/log/${PROGRAM}.*

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/33847.shtml

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

相关文章

Vue Router 导航守卫,多次执行的解决方案

Vue Router 是 Vue.js 官方提供的路由器,它用于处理单页应用(SPA)中的路由导航。在 Vue Router 中,导航守卫是非常重要的功能,它可以在路由跳转之前或之后执行一些特定的操作。但是,如果你不小心,导航守卫可能会多次执行,这可能会导致一些问题。本文将介绍如何避免导航…

cpu scheduling cpu调度

soft real-time Vs hard real-time scheduling Real-Time CPU Scheduling Can present obvious challengesSoft real-time systems – Critical real-time tasks have the highest priority, but no guarantee as to when tasks will be scheduledHard real-time systems – …

“Allegro评论管理:高效处理评价,提升顾客满意度”

波兰Allegro平台以其庞大的用户基础和丰富的商品种类&#xff0c;成为波兰乃至欧洲电商市场中的一颗璀璨明珠。如何高效管理和优化顾客评价&#xff0c;成为每个商家亟待解决的核心问题。正是基于这一背景&#xff0c;“无忧易售”——一款专注于Allegro评价管理的功能上线了&a…

【报错】在终端中输入repo命令后系统未能识别这个命令

1 报错 已经使用curl命令来下载repo工具,但是在终端中输入repo命令后系统未能识别这个命令。 2 分析 通常是因为repo

使用 Mac 数据恢复从 iPhoto 图库中恢复照片

我们每个人都会遇到这种情况&#xff1a;在意识到我们不想丢失照片之前&#xff0c;我们会永久删除 iPhoto 图库中的一些照片。永久删除这些照片后&#xff0c;是否可以从 iPhoto 图库中恢复照片&#xff1f;本文将指导您使用免费的 Mac 数据恢复软件从 iPhoto 中恢复照片。 i…

2024软件设计师笔记之考点版(一考就过):1-10

软件设计师之一考就过:成绩版 考点1:CPU、指令 真题1:CPU 执行算术运算或逻辑运算时,常将源操作数和结果暂存在(累加器(AC))中。 真题2:在程序的执行过程中,Cache与主存的地址映射是由(硬件自动)完成的。 真题3:计算机执行程序时,内存分为静态数据区、代码区、…

SQL Server 数据库分页技术详解:选择最佳方法优化查询性能”。

当今数据驱动的应用程序中&#xff0c;数据库分页技术在优化查询性能和提升用户体验中扮演着重要角色。在 SQL Server 环境下&#xff0c;开发者面对大数据集时&#xff0c;常常需要选择合适的分页方法以平衡功能需求和性能优化。本文将详细介绍 SQL Server 中几种主要的分页技…

【漏洞复现】华测监测预警系统——SQL注入漏洞

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 华测监测预警系统2.2版本存在sql注入&#xff0c;UserEdit接口S…

文华6声音预警公式-macd+kdj共振信号买卖点提示主图指标公式源码

文华6声音预警公式-macdkdj共振信号买卖点提示主图指标公式源码 指标公式逻辑&#xff1a; KDJC和MACDJC同时金叉时在K线的下面标记买字&#xff0c; KDSC和MACDSC同时死叉时候在K线上面标记卖字。 同时添加一下声音 指标公式源码&#xff1a; RSV:(CLOSE-LLV(LOW,9))/(H…

【华为OD机试B卷】解压报文、压缩报文还原(C++/Java/Python)

题目 题目描述 为了提升数据传输的效率,会对传输的报文进行压缩处理。输入一个压缩后的报文,请返回它解压后的原始报文。压缩规则:n[str],表示方括号内部的 str 正好重复 n 次。注意 n 为正整数(0 < n <= 100),str只包含小写英文字母,不考虑异常情况。输入描述 输…

零刻SER8 8845HS设置RAID磁盘阵列教程

SER8内置两个NVme硬盘位&#xff0c;支持硬盘RAID功能&#xff0c;目前支持以下几种RAID模式。 Volume&#xff08;卷&#xff09;&#xff1a;将多块硬盘拼接成一个大硬盘&#xff0c;也称为JBOD&#xff08;Just a Bunch Of Disks&#xff09;。它不要求硬盘容量相同&#xf…

干货收藏之追片神器

&#x1f3ac;追片神器&#x1f525;&#xff1a;cchifilm.com - 你的专属电影世界&#x1f31f; 在这个看脸的时代&#xff0c;我们都需要一款「追剧必备」的神器&#xff0c;今天我要安利给大家的是——cchifilm.com&#xff01;这是一个聚集了全球电影資訊和讨论的神奇网站…

【SQL Server数据库】简单查询

目录 用SQL语句完成下列查询。使用数据库为SCHOOL数据库 1. 查询学生的姓名、性别、班级名称&#xff0c;并把结果存储在一张新表中。 2. 查询男生的资料。 3. 查询所有计算机系的班级信息。 4&#xff0e;查询艾老师所教的课程号。 5. 查询年龄小于30岁的女同学的学号和姓名。…

使用 ks 安装 mysql

https://www.kubesphere.io/zh/docs/v3.3/application-store/built-in-apps/mysql-app/ 准备工作 您需要启用 OpenPitrix 系统。如何启用&#xff1f; 动手实验 步骤 1&#xff1a;从应用商店部署 MySQL 在 demo-project 的概览页面&#xff0c;点击左上角的应用商店。找到 …

昇思25天学习打卡营第二天|张量 Tensor

背景 华为组织了昇思25天学习学习营&#xff0c;提供免费算力&#xff0c;算力支持是昇腾Ascend 910芯片96G内存&#xff0c;很给力。 第一天的学习内容可以阅读文章&#xff1a; 昇思25天学习打卡营第一天|快速入门 学习内容 今天的学习内容是张量。如果线性代数学的好的同…

求字符串中所有整数的最小和(100%用例) C卷(JavaPythonC++Node.jsC语言)

输入字符串s,输出s中包含所有整数的最小和 说明 1. 字符串s,只包含 a-z A-Z +- ; 2. 合法的整数包括 1) 正整数 一个或者多个0-9组成,如 0 2 3 002 102 2)负整数 负号 - 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023 输入描述: 包含数字的字符串 …

VirtualBox 7.0.18 安装在D盘文件下,会提示目录不安全等信息,不让安装

VirtualBox 7.0.18 安装在D盘文件下&#xff0c;会提示目录不安全等信息&#xff0c;不让安装 功能快捷键参考链接 功能快捷键 问题&#xff1a; VirtualBox 7.0.18 安装在D盘文件下&#xff0c;会提示目录不安全等信息&#xff0c;不让安装 解决方式&#xff1a; 在D盘新建…

突发!OpenAI停止不支持国家API,7月9日开始执行

6月25日凌晨&#xff0c;有部分开发者收到了OpenAI的信&#xff0c;“根据数据显示&#xff0c;你的组织有来自OpenAl目前不支持的地区的API流量。从7月9日起&#xff0c;将采取额外措施&#xff0c;停止来自不在OpenAI支持的国家、地区名单上的API使用。” 但这位网友表示&am…

MySQL 5.7.42 主从复制环境搭建

MySQL 5.7.42 主从复制环境搭建 下载MySQL二进制包操作系统环境配置安装过程搭建从库 本次安装环境&#xff1a; OS版本&#xff1a;Red Hat Enterprise Linux Server release 6.8 (Santiago) MySQL版本&#xff1a;5.7.42 架构&#xff1a;同一台机器&#xff0c;多实例安装搭…

Spring有哪些依赖注入方式(注意目标类已经在IOC容器中存在)

Spring框架支持多种依赖注入&#xff08;Dependency Injection, DI&#xff09;方式&#xff0c;主要包括以下几种&#xff1a; 构造器注入&#xff08;Constructor Injection&#xff09;&#xff1a; 在这种方式中&#xff0c;依赖关系通过目标类的构造函数参数传递。Spring容…