SM2算法的加密签名消息语法规范(一)介绍

由于最近项目中需要根据国家密码局的规范(GM/T 0010)实现SM2密码算法加密签名消息数据的封装,花了些时间进行了下研究,现属文以记之~(^_−)☆   接下来先介绍sm2算法的消息语法规范,至于具体如何通过gmssl库去实现消息数据的封装,小编将在之后的文章中逐一讲解。OK, 进入正题~

首先我们知道PKCS#7中规定了6种数据内容:明文数据(Data)、签名数据(Signed-data),数字信封数据(Enveloped-data),带签名的数字信封数据(Signed-and-enveloped-data),摘要数据(Digested-data),加密数据(Encrypted-data)。(有兴趣的还可以看看rfc2315 (https://tools.ietf.org/html/rfc2315) ,全英文文档哦(*^▽^*)

同样国密局参考p7规范,对这6种类型进行了定义(具体见GM/T 0010规范http://www.doc88.com/p-7965091429139.html)。那国密规范中定义的6中数据类型与国际标准中的有什么区别呢? (•ิ_•ิ)?   

其实区别不是很大,都是将数据封装到pkcs7结构中(国际标准的消息数据封装通过openssl中的pkcs7模块实现,而国密规范的消息数据封装是通过gmssl中的pkcs7模块实现,GmSSL (http://gmssl.org) 是支持国密算法和标准的OpenSSL分支)。那么接下来我们细细聊一下GM/T 0010规范中的6中类型及与RFC中的区别。

1、类型标识符定义

RFC中各类型标识符定义如下:

对象标识符OID对象标识符定义GmSSL/OpenSSL中NID
1.2.840.113549.1.7.1数据类型dataNID_pkcs7_data
1.2.840.113549.1.7.2签名数据类型signedData NID_pkcs7_signed
1.2.840.113549.1.7.3数字信封数据类型envelopedDataNID_pkcs7_enveloped
1.2.840.113549.1.7.4签名及数字信封数据类型signedAndEnvelopedDataNID_pkcs7_signedAndEnveloped
1.2.840.113549.1.7.5摘要数据类型digestDataNID_pkcs7_digest
1.2.840.113549.1.7.6加密数据类型encryptedData NID_pkcs7_encrypted

GM/T 0010各类型标识符定义,详见下表:

对象标识符OID对象标识符定义GmSSL/OpenSSL中NID
1.2.156.10197.6.1.4.2SM2密码算法加密签名消息语法规范
1.2.156.10197.6.1.4.2.1数据类型data
1.2.156.10197.6.1.4.2.2签名数据类型signedData
1.2.156.10197.6.1.4.2.3数字信封数据类型envelopedData
1.2.156.10197.6.1.4.2.4签名及数据信封数据类型signedAndEnvelopedData
1.2.156.10197.6.1.4.2.5加密数据类型encrypedData
1.2.156.10197.6.1.4.2.6密钥协商类型keyAgreementInfo

 

 

相对于RFC规范,GM/T 0010规范中没有摘要数据类型,添加了密钥协商类型。且目前gmssl/openssl库中并不支持GM/T 0010规范中各类型标识符(注,小编用的是gmssl 2.4.2版本)。这也是我们后续编码构造国密消息语法规范的数据时需要解决的问题之一。

 

1、基本类型定义

Version

Version类型标明语法版本号。

Version ::= INTEGER

ContentEncryptionAlgorithmIdentifier

ContentEncryptionAlgorithmIdentifier类型标明一个数据加密算法。其OID见GM/T0006标准。

ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier

例如,gmssl库中已定义的SM4算法相关OID如下:

    NID_sms4_ecb,            /* OBJ_sms4_ecb                     1 2 156 10197 1 104 1 */
    NID_sms4_cbc,             /* OBJ_sms4_cbc                    1 2 156 10197 1 104 2 */
    NID_sms4_ofb128,        /* OBJ_sms4_ofb128              1 2 156 10197 1 104 3 */
    NID_sms4_cfb128,        /* OBJ_sms4_cfb128               1 2 156 10197 1 104 4 */
    NID_sms4_cfb1,            /* OBJ_sms4_cfb1                   1 2 156 10197 1 104 5 */
    NID_sms4_cfb8,            /* OBJ_sms4_cfb8                   1 2 156 10197 1 104 6 */
    NID_sms4_ctr,               /* OBJ_sms4_ctr                      1 2 156 10197 1 104 7 */
    NID_sms4_gcm,            /* OBJ_sms4_gcm                   1 2 156 10197 1 104 8 */
    NID_sms4_ccm,             /* OBJ_sms4_ccm                   1 2 156 10197 1 104 9 */
    NID_sms4_xts,               /* OBJ_sms4_xts                     1 2 156 10197 1 104 10 */
    NID_sms4_wrap,            /* OBJ_sms4_wrap                  1 2 156 10197 1 104 11 */
    NID_sms4_wrap_pad,    /* OBJ_sms4_wrap_pad          1 2 156 10197 1 104 12 */
    NID_sms4_ocb,              /* OBJ_sms4_ocb                    1 2 156 10197 1 104 100 */

DigestAlgorithmIdentifier

DigestAlgorithmIdentifier类型标识消息摘要算法,在GM/T0010标准中为SM3算法,其OID为:1.2.156.10197.1.401

DigestAlgorithmIdentifier ::= AlgorithmIdentifier

DigestEncryptionAlgorithmIdentifier

DigestEncryptionAlgorithmIdentifier类型标明一个签名算法,在GM/T0010标准中为SM2-1数字签名算法,其OID为:1.2.156.10197.1.301.1

DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier

ExtendedCertificatesAndCertificates

ExtendedCertificatesAndCertificate类型指定一个PKCS#6扩展证书或者一个X.509证书。这一类型见PKCS#6第6节推荐的语法:

ExtendedCertificateOrCertificate ::= CHOICE {
     certificate Certificate, -- X.509
     extendedCertificate [0] IMPLICIT ExtendedCertificate 
}

IssuerAndSerialNumber

IssuerAndSerialNumber类型标明一个证书颁发者可识别名和颁发者的证书序列号,可据此确定一份证书和与此证书对应的实体及公钥。

IssuerAndSerialNumber ::= SEQUENCE {
     issuer Name,
     serialNumber CertificateSerialNumber 
}

ContentInfo

ContentInfo类型标明了实体之间交换内容的通用语法结构,定义如下:

ContentInfo ::= SEQUENCE {
     contentType ContentType,
     content[0] EXPLICIT ANY DEFINED BY contentType OPTIONAL 
}
ContentType ::= OBJECT IDENTIFIER

其中:

ContentType 内容类型。它是一个对象标识符,这意味着它是由定义内容类型的权威分配的唯一整数字符串。也就是六种内容类型:data、signedData、envelopedData、signedAndEnvelopedData、digestddata和encryptedData对应的对象标识符。(对于SM2算法的消息语法规范即为GM/T 0010中定义的各类型标识符OID)

content 内容,可选

 

CertificateRevocationLists

CertificateRevocationLists类型标明一个证书撤销列表的集合。它的目的是让集合包含足够的信息来确定与该集合相关联的证书是否仍有效。

CertificateRevocationLists ::= SET OF CertificateRevocationList

 

2、明文数据类型 data

data数据类型结构定义如下:

Data ::= OCTET STRING

Data数据类型标识任意的字符串,比如ASCII文本文件。也就是说这样的字符串不需要有任何内部结构(当然也可以有),它们甚至可能是DER编码的数据。该类型与rfc2315中定义是一样一样的。

 

3、签名数据类型 signedData

signedData数据类型有任意类型的数和至少一个签名者的签名值组成。任意类型的数据能够同时被任意数量的签名者签名。signedData数据类型结构定义如下:

SignedData ::= SEQUENCE {
     version Version,
     digestAlgorithms DigestAlgorithmIdentifiers,
     contentInfo ContentInfo,
     certificates[0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
     crls[1] IMPLICIT CertificateRevocationLists OPTIONAL,
     signerInfos SignerInfos 
}
DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
SignerInfos ::= SET OF SignerInfo

结构中各项含义见下表

字段名称数据类型解释备注
versionVersion语法的版本号RFC2315 v1.5规范中这一版本号为1
digestAlgorithmsDigestAlgorithmIdentifiers消息摘要算法标识符的集合可以包含任意数量的元素,包括0。每一个元素标识一种消息摘要算法(和任何相应的参数)
contentInfoContentInfo被签名的数据内容,数据类型见GM/T 0009在GM/T 0010规范中该字段类型写的是SM2Signature,但根据GM/T 0009规范中的定义,SM2Signature是签名结果的数据类型,与该字段含义所说的被签名的数据内容不符,且签名值在signerInfos中会有记录。(小编大胆猜测是规范撰写人员粗心写错了(ー△ー;),应该为ContentInfo类型,即签名原文数据)
certificatesExtendedCertificatesAndCertificatesPKCS#6扩展证书和X.509证书的集合对于签名数据,这里可以存储签名者的证书
crlsCertificateRevocationLists证书撤销列表的集合撤销列表可以用来决定certificates域中的证书是否是“hot listed”的,但这不是必须的。
signerInfosSignerInfo集合每个签名者信息的集合 

国密规范定义的签名者信息结构定义与RFC中一致。只是某些字段的含义存在歧义(注意红色标注部分

3.1、SignerInfo类型

SignerInfo结构定义如下:

SignerInfo ::= SEQUENCE {
     version Version,
     issuerAndSerialNumber IssuerAndSerialNumber,
     digestAlgorithm DigestAlgorithmIdentifier,
     authenticatedAttributes[0] IMPLICIT Attributes OPTIONAL,
     digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
     encryptedDigest EncryptedDigest,
     unauthenticatedAttributes[1] IMPLICIT Attributes OPTIONAL 
}
EncryptedDigest ::= OCTET STRING

结构中各项含义见下表

字段名称数据类型含义
versionVersion语法的版本号。(RFC2315 v1.5规范中这一版本号为1)
issuerAndSerialNumberIssuerAndSerialNumber 一个证书颁发者可识别名和颁发者确定的证书序列号,可据此确定一份证书和与此证书对应的实体及公钥。
digestAlgorithmDigestAlgorithmIdentifier对内容进行摘要计算的消息摘要算法,GM/T 0010规范采用SM3算法
authenticatedAttributes[0]Attributes是经由签名者签名的属性的集合,该域是可选的。如果该域存在,该域中摘要的就是方法是对原文进行摘要计算结果
digestEncryptionAlgorithmDigestEncryptionAlgorithmIdentifierSM2-1椭圆曲线数字签名算法标识符
encryptedDigestOCTET STRING签名结果。注,GM/T0010规范中说明这里值是SM2Signature。编码格式为r||s.根据pkcs#7理解,填入的数据应为SM2Signature签名值结构数据经过DER编码后的数据
unauthenticatedAttributesAttributes不被签名的属性的集合

国密规范定义的签名者信息结构定义与RFC中一致。只是某些字段的含义有些区别(注意红色标注部分

4、数字信封数据类型envelopedData

数字信封envelopedData数据类型有加密数据和至少一个接收者的数据加密密钥的密文组成。其中加密数据是用数据加密密钥加密的,数据加密密钥是有接收者的公钥加密的

该类型用于为接收者的data、digestData或signedData三种类型的数据做数字信封。

envelopedData数据类型结构定义如下:

EnvelopedData ::= SEQUENCE {
     version Version,
     recipientInfos RecipientInfos,
     encryptedContentInfo EncryptedContentInfo 
}
RecipientInfos ::= SET OF RecipientInfo

EncryptedContentInfo ::= SEQUENCE {
     contentType ContentType,
     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
     encryptedContent[0] IMPLICIT EncryptedContent OPTIONAL,
     sharedInfo[1] IMPLICIT OCTET STRING OPTIONAL,
     sharedInfo[2] IMPLICIT OCTET STRING OPTIONAL
}
EncryptedContent ::= OCTET STRING

envelopedData结构中各项含义见下表

字段名称数据类型含义
versionVersion语法的版本号,(RFC2315 v1.5规范中这一版本号为0)
recipientInfosRecipientInfos每个接收者信息的集合,至少要有一个接收者。
encryptedContentInfoEncryptedContentInfo已加密的内容信息

encryptedContentInfo结构中各项含义见下表

字段名称数据类型含义
contentTypeContentType内容的类型
contentEncryptionAlgorithmContentEncryptionAlgorithm内容加密算法(和相关的参数)
encryptedContentEncryptedContent内容加密结果,可选。如果该字段不存在,则必须通过其他方式提供其预期值。填入数据为国密规范定义的密文保护结构经过DER编码后的数据
sharedInfoOCTET STRING协商好的共享信息,可选
sharedInfoOCTET STRING协商好的共享信息,可选

国密规范中定义的数字信封结构相较于RFC规范中,新增了2个字段用于存放协商好的共享信息。

4.1、RecipientInfo类型

每个接收者信息用RecipientInfo类型表示,其类型结构定义如下:

RecipientInfo ::= SEQUENCE {
     version Version,
     issuerAndSerialNumber IssuerAndSerialNumber,
     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
     encryptedKey EncryptedKey 
}
EncryptedKey ::= OCTET STRING

结构中各项含义见下表

字段名称数据类型含义
versionVersion语法的版本号。(RFC2315 v1.5规范中这一版本号为0)
issuerAndSerialNumberIssuerAndSerialNumber一个证书颁发者可识别名和颁发者确定的证书序列号,可据此确定一份证书和与此证书对应的实体及公钥
keyEncryptionAlgorithmKeyEncryptionAlgorithmIdentifier用接收者公钥加密数据加密密钥的算法,为SM2-3椭圆曲线加密算法
encryptedKeyEncryptedKey数据加密密钥密文SM2Cipher,其定义见GM/T 0009。填入数据应为SM2Cipher结构经过DER编码后的数据

接收者信息类型结构定义与RFC中差不多。只是某些字段的含义有些区别(注意红色标注部分

5、签名及数字信封数据类型signedAndEnvelpedData

signedAndEnvelopedData数据类型有任意类型的加密数据、至少一个接收者的数据加密密钥和至少一个签名者的签名组成。其结构定义如下:

SignedAndEnvelopedData ::= SEQUENCE {
     version Version,
     recipientInfos RecipientInfos,
     digestAlgorithms DigestAlgorithmIdentifiers,
     encryptedContentInfo EncryptedContentInfo,
     certificates[0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
     crls[1] IMPLICIT CertificateRevocationLists OPTIONAL,
     signerInfos SignerInfos 
}

结构中各项含义见下表

字段名称数据类型含义
versionVersion语法的版本号。(RFC2315 v1.5规范中这一版本号为1)
recipientInfosRecipientInfos每个接收者信息的集合,至少一个元素
digestAlgorithmsDigestAlgorithmIdentifiers消息摘要算法标识符的集合
encryptedContentInfoEncryptedContentInfo已加密的内容,可以是任何定义的数据类型
certificatesExtendedCertificatesAndCertificatesPKCS#6扩展证书或者一个X.509证书的集合,是可选的
crlsCertificateRevocationLists证书撤销列表的集合
signerInfosSignerInfos每个签名者的集合,至少要有一个元素

国密规范定义的签名及数字信封类型结构与RFC中一样。

6、加密数据类型encryptedData

encryptedData数据类型有任意类型的已加密的数据组成,数据类型既没有接收者也没有加密的数据加密密钥。其结构定义如下:

EncryptedData ::= SEQUENCE {
     version Version,
     encryptedContentInfo EncryptedContentInfo 
}

结构中各项含义见下表

字段名称数据类型含义
versionVersion语法的版本号。(RFC2315 v1.5规范中这一版本号为0)
encryptedContentInfoEncryptedContentInfo已加密的内容信息

国密规范中该类型结构与RFC中一致。

7、密钥协商类型keyAgreementInfo

密钥协商数据类型标明两个用户之间建立一个共享秘密密钥的结构,通过这种方式能够确定一个共享秘密密钥的值。

该类型用于两个用户为产生共享秘密密钥进行的公共参数交换。

KeyAgreementInfo ::= SEQUENCE {
     version Version(1),
     tempPublicKeyR SM2PublicKey,
     userCertificate Certificate,
     userID OCTET STRING
}

结构中各项含义见下表

字段名称数据类型含义
versionVersion语法的版本号。
tempPublicKeyRSM2PublicKey临时公钥,结构定义见GM/T 0006
userCertificateCertificate用户证书
userIDOCTET STRING用户标识

 

 

OK,GM/T 0010规范解析介绍到这,之后的文章中将聊聊如何构造SM2算法的消息数据。。。。。。。。。。 (((┏(; ̄▽ ̄)┛装完逼就跑

 

 

 

 

sm2算法是一种国家密码学标准算法,它主要用于椭圆曲线公钥密码体制中的加密和数字签名sm2算法基于椭圆曲线离散对数问题,具有安全性和高效性的特点。 sm2算法的C语言实现主要包括以下几个步骤: 1. 选择椭圆曲线参数:sm2算法使用的是国家标准椭圆曲线参数,可以在标准文档中找到。选择合适的参数,初始化椭圆曲线。 2. 生成密钥对:使用随机数生成器生成一个私钥,并通过椭圆曲线上的点运算得到对应的公钥。 3. 加密过程:假设要加密的明文为M,首先将M转换成点P,再生成一个随机数k。通过点运算得到C1=kG,其中G为基点。然后计算点S=kP,将S的x坐标转换成字节数组,作为SM3算法的输入,得到哈希值H。最后计算C2=M⨁H,C3=k^-1·(hash(kP)+C2)。 4. 解密过程:给定密文C=(C1,C2,C3),首先计算C1的k倍点为kC1,并将kC1的x坐标作为SM3算法的输入,得到哈希值H。然后计算C2=M⨁H,并利用C1的k倍点计算kP。最后计算hash(kP)+C2,乘以C3的k^-1得到明文M。 5. 数字签名过程:给定要签名消息M和私钥d,首先计算消息的哈希值H。然后生成一个随机数k,并通过点运算得到点R=kG。将R的x坐标转换成字节数组,作为SM3算法的输入,得到哈希值h。计算s=(h+d·r)·⁻¹·k。最后签名为(R,s)。 以上是sm2算法的简要介绍和C语言实现的整体步骤,实现过程中需注意安全性和正确性。具体的C语言代码实现需要详细研究和阅读sm2算法的相关标准文档,理解椭圆曲线运算和密码哈希算法的具体细节,然后按照算法规范进行编码实现。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值