前文可参考:SM2算法的加密签名消息语法规范(三)如何构造signedData_天对地,雨对风的博客-CSDN博客系列。
这里直接讲openssl asn1解析和封装的部分代码。
国密 p7格式标准,参考:GMT0010-2012
1、p7 签名结构:
编写结构体GMTSignedData.h
#ifndef _GMTSignedData_H
#define _GMTSignedData_H
#include <openssl\asn1.h>
#include <openssl\asn1t.h>
#include <openssl\safestack.h>
#include <openssl\evp.h>
#include <openssl\pkcs7.h>
#include <openssl\x509.h>
# 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)
解码测试:文章来源:https://www.toymoban.com/news/detail-515776.html
void test()
{
//puchData为数据内容,nDataLen为数据长度。自行定义。
SM2ContentInfo* p7 = NULL;
p7 = d2i_SM2ContentInfo(&p7, &puchData, nDataLen);
char oid1[255] = { 0 };
OBJ_obj2txt(oid1, 255, p7->type, 0);
}
至此可以解码成功,编码参考其他文章。文章来源地址https://www.toymoban.com/news/detail-515776.html
到了这里,关于国密SM2算法的加密签名消息语法封装解析p7格式signedData的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!