安全电子签章密码技术规范 GM/T 0031 | GB∕T 38540 格式OPENSSL封装解析

印章签章格式的数据结构体封装,解析(asn.1编码)

参考规范 安全电子签章密码技术规范 GM/T 0031 2014 GB∕T 38540-2020

openssl 带的ans.1编码封装解析,方便快捷.只要按照具体结构定义好规则,可直接生成解析,构造函数

typedef struct CertDigestObj_t {
    ASN1_PRINTABLESTRING *type;
    ASN1_OCTET_STRING *value;
}CertDigestObj;

// 印章头
typedef struct SES_Header_t {
    ASN1_IA5STRING *id; //标识固定为ES
    int32_t version; //印章版本号
    ASN1_IA5STRING *vid; //厂商标识
}SES_Header;

typedef struct SES_ESPictureInfo_t {
    ASN1_IA5STRING *type; //印章图片类型png, jpg等
    ASN1_OCTET_STRING *data; //印章图片数据
    int32_t width; //印章宽度,单位毫米
    int32_t height; //印章高度,单位毫米
}SES_ESPictureInfo;

typedef struct SESv1_ESPropertyInfo_t {
    int32_t type; //印章类型
    ASN1_UTF8STRING *name; //印章名称
    STACK_OF(ASN1_OCTET_STRING) *certs; //签章者的列表(最终用章的人的证书列表)
    ASN1_UTCTIME *createDate;
    ASN1_UTCTIME *validStart;
    ASN1_UTCTIME *validEnd;
}SESv2_ESPropertyInfo;

typedef struct SESv4_ESPropertyInfo_t {
    int32_t type;
    ASN1_UTF8STRING *name;
    int32_t certListType; //v4版本 有类型,证书列表或者证书摘要的列表
    STACK_OF(ASN1_OCTET_STRING) *certs;
    STACK_OF(CertDigestObj) *certDigestList;
    ASN1_GENERALIZEDTIME *createDate;
    ASN1_GENERALIZEDTIME *validStart;
    ASN1_GENERALIZEDTIME *validEnd;
}SESv4_ESPropertyInfo;

typedef struct SESv1_SealInfo_t {
    SES_Header *header;
    ASN1_IA5STRING *esid; // 印章的唯一标识码
    SESv2_ESPropertyInfo *property;
    SES_ESPictureInfo *picture;
    STACK_OF(X509_EXTENSION) *extDatas;
}SESv2_SealInfo;

typedef struct SESv4_SealInfo_t {
    SES_Header *header;
    ASN1_IA5STRING *esid;
    SESv4_ESPropertyInfo *property;
    SES_ESPictureInfo *picture;
    STACK_OF(X509_EXTENSION) *extDatas;
}SESv4_SealInfo;


typedef struct SESv2_SignInfo_t {
    ASN1_OCTET_STRING *cert;
    ASN1_OBJECT *signalgid;
    ASN1_BIT_STRING *signedvalue;
}SESv2_SignInfo;

typedef struct SESv2_Seal_t {
    SESv2_SealInfo *sealinfo;
    SESv2_SignInfo *signinfo;
}SESv2_Seal;

typedef struct SESv4_Seal_t {
    SESv4_SealInfo *sealinfo;
    ASN1_OCTET_STRING *cert;
    ASN1_OBJECT *signalgid;
    ASN1_BIT_STRING *signedvalue;
}SESv4_Seal;

typedef struct TBSv2_Sign_t {
    int32_t version;
    SESv2_Seal *eseal;
    ASN1_BIT_STRING *timeinfo;
    ASN1_BIT_STRING *datahash;
    ASN1_IA5STRING *propertyinfo;
    ASN1_OCTET_STRING *cert;
    ASN1_OBJECT *signalgid;
    ASN1_OCTET_STRING *signalgname;
}TBSv2_Sign;

typedef struct TBSv4_Sign_t {
    int32_t version;
    SESv4_Seal *eseal;
    ASN1_GENERALIZEDTIME *timeinfo;
    ASN1_BIT_STRING *datahash;
    ASN1_IA5STRING *propertyinfo;
    STACK_OF(X509_EXTENSION) *extDatas;
}TBSv4_Sign;

typedef struct SESv2_Signature_t {
    TBSv2_Sign *tosign;
    ASN1_BIT_STRING *signature;
}SESv2_Signature;

typedef struct SESv4_Signature_t {
    TBSv4_Sign *tosign;
    ASN1_OCTET_STRING *cert;
    ASN1_OBJECT *signalgid;
    ASN1_BIT_STRING *signedvalue;
    ASN1_BIT_STRING *timestamp;
}SESv4_Signature;

ASN1_SEQUENCE(CertDigestObj) = {
    ASN1_SIMPLE(CertDigestObj, type, ASN1_PRINTABLESTRING),
    ASN1_SIMPLE(CertDigestObj, value, ASN1_OCTET_STRING)
} static_ASN1_NDEF_SEQUENCE_END(CertDigestObj)

ASN1_SEQUENCE(SES_Header) = {
    ASN1_SIMPLE(SES_Header, id, ASN1_IA5STRING),
    ASN1_EMBED(SES_Header, version, INT32),
    ASN1_SIMPLE(SES_Header, vid, ASN1_IA5STRING)
} static_ASN1_NDEF_SEQUENCE_END(SES_Header)

ASN1_SEQUENCE(SES_ESPictureInfo) = {
    ASN1_SIMPLE(SES_ESPictureInfo, type, ASN1_IA5STRING),
    ASN1_SIMPLE(SES_ESPictureInfo, data, ASN1_OCTET_STRING),
    ASN1_EMBED(SES_ESPictureInfo, width, INT32),
    ASN1_EMBED(SES_ESPictureInfo, height, INT32)
} static_ASN1_NDEF_SEQUENCE_END(SES_ESPictureInfo)


ASN1_SEQUENCE(SESv2_ESPropertyInfo) = {
    ASN1_EMBED(SESv2_ESPropertyInfo, type, INT32),
    ASN1_SIMPLE(SESv2_ESPropertyInfo, name, ASN1_UTF8STRING),
    ASN1_SEQUENCE_OF_OPT(SESv2_ESPropertyInfo, certs, ASN1_OCTET_STRING),
    ASN1_SIMPLE(SESv2_ESPropertyInfo, createDate, ASN1_UTCTIME),
    ASN1_SIMPLE(SESv2_ESPropertyInfo, validStart, ASN1_UTCTIME),
    ASN1_SIMPLE(SESv2_ESPropertyInfo, validEnd, ASN1_UTCTIME)
} static_ASN1_NDEF_SEQUENCE_END(SESv2_ESPropertyInfo)

ASN1_SEQUENCE(SESv4_ESPropertyInfo) = {
    ASN1_EMBED(SESv4_ESPropertyInfo, type, INT32),
    ASN1_SIMPLE(SESv4_ESPropertyInfo, name, ASN1_UTF8STRING),
    ASN1_EMBED(SESv4_ESPropertyInfo, certListType, INT32),
    ASN1_SEQUENCE_OF_OPT(SESv4_ESPropertyInfo, certs, ASN1_OCTET_STRING),
    ASN1_SEQUENCE_OF_OPT(SESv4_ESPropertyInfo, certDigestList, CertDigestObj),
    ASN1_SIMPLE(SESv4_ESPropertyInfo, createDate, ASN1_GENERALIZEDTIME),
    ASN1_SIMPLE(SESv4_ESPropertyInfo, validStart, ASN1_GENERALIZEDTIME),
    ASN1_SIMPLE(SESv4_ESPropertyInfo, validEnd, ASN1_GENERALIZEDTIME)
} static_ASN1_NDEF_SEQUENCE_END(SESv4_ESPropertyInfo)

ASN1_SEQUENCE(SESv2_SealInfo) = {
    ASN1_SIMPLE(SESv2_SealInfo, header, SES_Header),
    ASN1_SIMPLE(SESv2_SealInfo, esid, ASN1_IA5STRING),
    ASN1_SIMPLE(SESv2_SealInfo, property, SESv2_ESPropertyInfo),
    ASN1_SIMPLE(SESv2_SealInfo, picture, SES_ESPictureInfo),
    ASN1_IMP_SET_OF_OPT(SESv2_SealInfo, extDatas, X509_EXTENSION, 0)
} static_ASN1_NDEF_SEQUENCE_END(SESv2_SealInfo)
IMPLEMENT_ASN1_FUNCTIONS(SESv2_SealInfo)

ASN1_SEQUENCE(SESv4_SealInfo) = {
    ASN1_SIMPLE(SESv4_SealInfo, header, SES_Header),
    ASN1_SIMPLE(SESv4_SealInfo, esid, ASN1_IA5STRING),
    ASN1_SIMPLE(SESv4_SealInfo, property, SESv4_ESPropertyInfo),
    ASN1_SIMPLE(SESv4_SealInfo, picture, SES_ESPictureInfo),
    ASN1_SEQUENCE_OF_OPT(SESv4_SealInfo, extDatas, X509_EXTENSION)
} static_ASN1_NDEF_SEQUENCE_END(SESv4_SealInfo)
IMPLEMENT_ASN1_FUNCTIONS(SESv4_SealInfo)

ASN1_SEQUENCE(SESv2_SignInfo) = {
    ASN1_SIMPLE(SESv2_SignInfo, cert, ASN1_OCTET_STRING),
    ASN1_SIMPLE(SESv2_SignInfo, signalgid, ASN1_OBJECT),
    ASN1_SIMPLE(SESv2_SignInfo, signedvalue, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(SESv2_SignInfo)
IMPLEMENT_ASN1_FUNCTIONS(SESv2_SignInfo)

ASN1_SEQUENCE(SESv2_Seal) = {
    ASN1_SIMPLE(SESv2_Seal, sealinfo, SESv2_SealInfo),
    ASN1_SIMPLE(SESv2_Seal, signinfo, SESv2_SignInfo)
} ASN1_SEQUENCE_END(SESv2_Seal)
IMPLEMENT_ASN1_FUNCTIONS(SESv2_Seal)

ASN1_SEQUENCE(SESv4_Seal) = {
    ASN1_SIMPLE(SESv4_Seal, sealinfo, SESv4_SealInfo),
    ASN1_SIMPLE(SESv4_Seal, cert, ASN1_OCTET_STRING),
    ASN1_SIMPLE(SESv4_Seal, signalgid, ASN1_OBJECT),
    ASN1_SIMPLE(SESv4_Seal, signedvalue, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(SESv4_Seal)
IMPLEMENT_ASN1_FUNCTIONS(SESv4_Seal)

ASN1_SEQUENCE(TBSv2_Sign) = {
    ASN1_EMBED(TBSv2_Sign, version, INT32),
    ASN1_SIMPLE(TBSv2_Sign, eseal, SESv2_Seal),
    ASN1_SIMPLE(TBSv2_Sign, timeinfo, ASN1_BIT_STRING),
    ASN1_SIMPLE(TBSv2_Sign, datahash, ASN1_BIT_STRING),
    ASN1_SIMPLE(TBSv2_Sign, propertyinfo, ASN1_IA5STRING),
    ASN1_SIMPLE(TBSv2_Sign, cert, ASN1_OCTET_STRING),
    ASN1_OPT(TBSv2_Sign, signalgid, ASN1_OBJECT),
    ASN1_OPT(TBSv2_Sign, signalgname, ASN1_OCTET_STRING)
} static_ASN1_NDEF_SEQUENCE_END(TBSv2_Sign)
IMPLEMENT_ASN1_FUNCTIONS(TBSv2_Sign)

ASN1_SEQUENCE(TBSv4_Sign) = {
    ASN1_EMBED(TBSv4_Sign, version, INT32),
    ASN1_SIMPLE(TBSv4_Sign, eseal, SESv4_Seal),
    ASN1_SIMPLE(TBSv4_Sign, timeinfo, ASN1_GENERALIZEDTIME),
    ASN1_SIMPLE(TBSv4_Sign, datahash, ASN1_BIT_STRING),
    ASN1_SIMPLE(TBSv4_Sign, propertyinfo, ASN1_IA5STRING),
    ASN1_SEQUENCE_OF_OPT(TBSv4_Sign, extDatas, X509_EXTENSION)
} static_ASN1_NDEF_SEQUENCE_END(TBSv4_Sign)
IMPLEMENT_ASN1_FUNCTIONS(TBSv4_Sign)

ASN1_SEQUENCE(SESv2_Signature) = {
    ASN1_SIMPLE(SESv2_Signature, tosign, TBSv2_Sign),
    ASN1_SIMPLE(SESv2_Signature, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(SESv2_Signature)
IMPLEMENT_ASN1_FUNCTIONS(SESv2_Signature)

ASN1_SEQUENCE(SESv4_Signature) = {
    ASN1_SIMPLE(SESv4_Signature, tosign, TBSv4_Sign),
    ASN1_SIMPLE(SESv4_Signature, cert, ASN1_OCTET_STRING),
    ASN1_SIMPLE(SESv4_Signature, signalgid, ASN1_OBJECT),
    ASN1_SIMPLE(SESv4_Signature, signedvalue, ASN1_BIT_STRING),
    ASN1_OPT(SESv4_Signature, timestamp, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(SESv4_Signature)
IMPLEMENT_ASN1_FUNCTIONS(SESv4_Signature)

签章,印章的解析,d2i,i2d类似这样的函数,只要按照结构定义好,openssl是自动生成的宏函数

SESv2_Signature *sesv2_sign = NULL;
sesv2_sign = d2i_SESv2_Signature(NULL, (const unsigned char**)&seal, seal_len);

SESv4_Signature *sesv4_sign = NULL;
sesv4_sign = d2i_SESv4_Signature(NULL, (const unsigned char**)&seal, seal_len);

签章,印章的数据格式生成,参考(只包含了整个结构,里面没有涉及到算法)

SESv2_Signature sesv2_sign = SESv2_Signature_new();

ASN1_OBJECT *obj;
obj = OBJ_nid2obj(OBJ_create("1.2.3.4", "NewOID", "New Object Identifier"));
sesv2_sign->tosign->eseal->signinfo->signalgid = obj;

sesv2_sign->tosign->signalgid = obj;

sesv2_sign->tosign->eseal->sealinfo->property->certs = sk_new_null();
ASN1_OCTET_STRING *utf8 = ASN1_OCTET_STRING_new();
ASN1_STRING_set(utf8, "tes1", 4);
sk_push(sesv2_sign->tosign->eseal->sealinfo->property->certs, utf8);

utf8 = ASN1_OCTET_STRING_new();
ASN1_STRING_set(utf8, "tes9", 4);
sk_push(sesv2_sign->tosign->eseal->sealinfo->property->certs, utf8);

unsigned char *seal = NULL;
int seal_len = 0;

seal_len = i2d_SESv2_Signature(sesv2_sign, &seal);
SESv2_Signature_free(sesv2_sign);