国密SM2算法的加密签名消息语法封装解析p7格式signedData
前文可参考:SM2算法的加密签名消息语法规范(三)如何构造signedData_天对地,雨对风的博客-CSDN博客系列。
这里直接讲openssl asn1解析和封装的部分代码。
国密 p7格式标准,参考:GMT0010-2012
1、p7 签名结构:

编写结构体GMTSignedData.h
#ifndef _GMTSignedData_H
#define _GMTSignedData_H#include
#include
#include
#include
#include
#include # ifdef __cplusplus
extern "C" {
# endif/*oid refer to GM/T 0006*/
#define OID_SM2_1 "1.2.156.10197.1.301.1" /*sm2-1 数字签名算法 */
#define OID_SM2_3 "1.2.156.10197.1.301.3" /*sm2-3 公钥加密算法*/
#define OID_SM3 "1.2.156.10197.1.401" /*SM3密码杂凑算法*/
#define OID_SM4 "1.2.156.10197.1.104" /*SM4分组密码算法*//*oid refer to GM/T 0010*/
#define OID_SM2_Data "1.2.156.10197.6.1.4.2.1" //SM2算法消息语法规范- 数据类型
#define OID_SM2_Signed "1.2.156.10197.6.1.4.2.2" //SM2算法消息语法规范- 签名数据类型
#define OID_SM2_Enveloped "1.2.156.10197.6.1.4.2.3" //SM2算法消息语法规范- 数字信封数据类型
#define OID_SM2_SignedAndEnveloped "1.2.156.10197.6.1.4.2.4" //SM2算法消息语法规范- 签名及数字信封数据类型
#define OID_SM2_Encrypted "1.2.156.10197.6.1.4.2.5" //SM2算法消息语法规范- 加密数据类型
#define OID_SM2_KeyAgreementInfo "1.2.156.10197.6.1.4.2.6" //SM2算法消息语法规范- 密钥协商数据类型typedef struct sm2_signed_st {ASN1_INTEGER *version; /* version 1 */STACK_OF(X509_ALGOR) *md_algs; /* md used */struct SM2ContentInfo_st *contents;STACK_OF(X509) *cert; /* [ 0 ] */STACK_OF(X509_CRL) *crl; /* [ 1 ] */STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
} SM2_SIGNED;typedef struct SM2_SignedData_st {int type;union {/* NID_pkcs7_data */ASN1_OCTET_STRING *data;/* sm2_signed */SM2_SIGNED *sign;/* NID_pkcs7_enveloped */PKCS7_ENVELOPE *enveloped;/* NID_pkcs7_signedAndEnveloped */PKCS7_SIGN_ENVELOPE *signed_and_enveloped;/* NID_pkcs7_digest */PKCS7_DIGEST *digest;/* NID_pkcs7_encrypted */PKCS7_ENCRYPT *encrypted;/* Anything else */ASN1_TYPE *other;} d;
} SM2_SignedData;DECLARE_ASN1_FUNCTIONS(SM2_SignedData)typedef struct SM2ContentInfo_st
{ASN1_OBJECT *type;SM2_SignedData* sd;
} SM2ContentInfo;DECLARE_ASN1_FUNCTIONS(SM2ContentInfo)# ifdef __cplusplus
}
# endif#endif //_GMTSignedData_H
注意:SM2_SignedData_st结构中的sign类型修改为SM2_SIGNED,sm2_signed_st结构中的contents 类型修改为SM2_ContentInfo_st。
GMTSignedData.cpp
#pragma once#include "stdafx.h"
#include "GMTSignedData.h"ASN1_NDEF_SEQUENCE(SM2_SIGNED) = {ASN1_SIMPLE(SM2_SIGNED, version, ASN1_INTEGER),ASN1_SET_OF(SM2_SIGNED, md_algs, X509_ALGOR),ASN1_SIMPLE(SM2_SIGNED, contents, SM2ContentInfo),ASN1_IMP_SEQUENCE_OF_OPT(SM2_SIGNED, cert, X509, 0),ASN1_IMP_SET_OF_OPT(SM2_SIGNED, crl, X509_CRL, 1),ASN1_SET_OF(SM2_SIGNED, signer_info, PKCS7_SIGNER_INFO)
} ASN1_NDEF_SEQUENCE_END(SM2_SIGNED)IMPLEMENT_ASN1_FUNCTIONS(SM2_SIGNED)ASN1_CHOICE(SM2_SignedData) =
{ASN1_SIMPLE(SM2_SignedData, d.data, ASN1_OCTET_STRING),ASN1_OPT(SM2_SignedData, d.sign, SM2_SIGNED),ASN1_OPT(SM2_SignedData, d.enveloped, PKCS7_ENVELOPE),ASN1_OPT(SM2_SignedData, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE),ASN1_OPT(SM2_SignedData, d.digest, PKCS7_DIGEST),ASN1_OPT(SM2_SignedData, d.encrypted, PKCS7_ENCRYPT),ASN1_OPT(SM2_SignedData, d.other, ASN1_ANY)
}ASN1_CHOICE_END(SM2_SignedData)
IMPLEMENT_ASN1_FUNCTIONS(SM2_SignedData)ASN1_SEQUENCE(SM2ContentInfo) =
{ASN1_SIMPLE(SM2ContentInfo, type, ASN1_OBJECT),ASN1_EXP(SM2ContentInfo, sd, SM2_SignedData, 0)
}ASN1_SEQUENCE_END(SM2ContentInfo)
IMPLEMENT_ASN1_FUNCTIONS(SM2ContentInfo)
解码测试:
void test()
{//puchData为数据内容,nDataLen为数据长度。自行定义。SM2ContentInfo* p7 = NULL;p7 = d2i_SM2ContentInfo(&p7, &puchData, nDataLen);char oid1[255] = { 0 };OBJ_obj2txt(oid1, 255, p7->type, 0);
}
至此可以解码成功,编码参考其他文章。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
