您的位置:首页 > 其它

SM2密码算法应用分析

2014-04-14 21:58 435 查看

1 曲线

参考《SM2椭圆曲线公钥密码算法第1部分:总则》(GM/T0003.1-2012),2012-03-21发布版本。

1.1 Fp上的椭圆曲线

定义在Fp(p是大于3的素数)上的椭圆曲线方程为:

y2 = x3+ax+b, a;b∈ Fp,且(4a3+27b2) modp ̸= 0。--------------------(1)

椭圆曲线E(Fp)定义为:

E(Fq) = {(x;y)|x;y∈ Fp,且满足方程(1)}∪{O},其中O是无穷远点。

椭圆曲线E(Fp)上的点的数目用#E(Fq)表示,称为椭圆曲线E(Fp)的阶。

1.2 F2m上的椭圆曲线

定义在F2m上的椭圆曲线方程为:

y2+xy = x3+ax2+b,a;b∈ F2m,且b ̸= 0。--------------------
(2)

椭圆曲线E(F2m )定义为:

E(F2m) = {(x;y)|x;y∈ F2m,且满足方程(2)}∪{O},其中O是无穷远点。

椭圆曲线E(F2m )上的点的数目用#E(F2m)表示,称为椭圆曲线E(F2m )的阶。

2 曲线参数

参考《SM2椭圆曲线公钥密码算法第5部分:参数定义》(GM/T0003.5-2012),2012-03-21发布版本。

SM2只有Fp上的椭圆曲线的推荐参数

推荐使用素数域256位椭圆曲线。

椭圆曲线方程:y2 = x3 + ax + b。

曲线参数:

p=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFFFFFFFFFF 00000000 FFFFFFFF FFFFFFFF

a=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFFFFFFFFFF 00000000 FFFFFFFF FFFFFFFC

b=28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7F39789F5 15AB8F92 DDBCBD41 4D940E93

n=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF7203DF6B 21C6052B 53BBF409 39D54123

Gx=32C4AE2C 1F198119 5F990446 6A39C9948FE30BBF F2660BE1 715A4589 334C74C7

Gy=BC3736A2 F4F6779C 59BDCEE3 6B692153D0A9877C C62A4740 02DF32E5 2139F0A0

国际通用的X9.62命名曲线有很多,下面略举2条Fp曲线:

256bits:

p=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF

a=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC

b=5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B

n=FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551

Gx=6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296

Gy=4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5

h=1

192bits:

p=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF

a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC

b=64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1

n=FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831

Gx=188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012

Gy=7192B95FFC8DA78631011ED6B24CDD573F977A11E794811

h=1

3 密钥语法

参考《SM2密码算法使用规范》(GM/T0009-2012),2012-11-22发布版本。

3.1 SM2私钥

SM2私钥是一个大于等于1并且小于n-1的整数,记为k,长度为32字节。

SM2PrivateKey ::= INTEGER

《GMT0010SM2密码算法加密签名消息语法规范》中定义了和X9.62相同的私钥语法:

ECPrivateKey{CURVES:IOSet}::= SEQUENCE {

version INTEGER {ecPrivkeyVer1(1)}(ecPrivkeyVer1),

privateKey SM2PrivateKey,(其实X9.62中,这里是OCTETSTRING,而不是上面的INTEGER)

parameters[0] Parameters{{IOSet}}OPTIONAL,

publicKey [1] SM2PublicKey

}

其实上面的定义还不够完善,真正要实现私钥交换的话,还要封装成PKCS#8格式:

PrivateKeyInfo ::=SEQUENCE {

version Version,

privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,

privateKey PrivateKey,

attributes [0] IMPLICIT Attributes OPTIONAL

}

Version ::=INTEGER (目前取0)

PrivateKeyAlgorithmIdentifier ::=AlgorithmIdentifier(和公钥定义相同)

PrivateKey ::=OCTET STRING(即是ECPrivateKey)

3.2 SM2公钥

SM2公钥是SM2曲线上的一个点,由横坐标和纵坐标两个分量来表示,记为(x,y),简记为Q,长度为64字节。Q=kG,是私钥与曲线基点的乘积。

SM2PublicKey::=BIT STRING

SM2PublicKey为类型,内容为04||X||Y,其中X和Y分别标识公钥的X分量和Y分量。其长度各为256位。

《GMT0010SM2密码算法加密签名消息语法规范》中定义了和X9.62相同的主题公钥语法:

SubjectPublicKeyInfo ::= SEQUENCE {

algorithm AlgorithmIdentifier{{ECPKAlgorithms}},

subjectPublicKey SM2PublicKey

}

AlgorithmIdentifier::= SEQUENCE {

algorithm OBJECTIDENTIFIER,

parameters ANY DEFINED BY algorithm OPTIONAL

}

algorithm OID和X9.62相同:iso(1) member-body(2) us(840)ansi-x962(10045) keyType(2) ecPublicKey(1)

Parameters::= CHOICE {

ecParametersECParameters,

namedCurveObjectIdentifier,

implicitlyCA NULL

}

参数是命名曲线OID:iso(1) member-body(2) cn(156) ccstc(10197) 1.301,即SM2。公钥数据是SM2PublicKey::=
BIT STRING,即04||X||Y

3.3 加密后的SM2密钥对

SM2EnvelopedKey::=SEQUENCE{

symAlgID AlgorithmIdentifier,--对称密码算法标识

symEncryptedKey SM2Cipher,--对称密钥密文,参见

Sm2PublicKey SM2PublicKey,--SM2公钥

Sm2EncryptedPrivateKey BITSTRING --SM2私钥密文(对称加密)

}

3.4 用户标识ID的默认值

无特殊约定的情况下,用户标识ID的长度为16字节,其默认值从左至右依次为:

0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38。

4 运算过程

4.1 签名

设待签名的消息为M,为了获取消息M的数字签名(r,s),作为签名者的用户A应实现以下运算步骤:

A1:置M’=ZA∥M;ZA= Hv(ENTLA||IDA||a||b||Gx||Gy||Ax||Ay);ENTLA为IDA的比特长度,2字节;IDA用户标识默认值见上节;a,b,Gx,Gy见曲线参数;Ax,Ay为公钥坐标

A2:计算e = Hv(M’),按规则将e的数据类型转换为整数;

A3:用随机数发生器产生随机数k∈[1,n-1];

A4:计算椭圆曲线点(x1,y1)=[k]G,按规则将x1的数据类型转换为整数;

A5:计算r=(e+x1) modn,若r=0或r+k=n则返回A3;

A6:计算s = ((1 +dA)^−1 • (k − r • dA)) mod n,若s=0则返回A3;

A7:按规则将r、s的数据类型转换为字节串,消息M的签名为(r,s)。

注:按上面的曲线参数,则r和s分别为32字节,即签名值为64字节。但按照《SM2密码算法使用规范(GM/T
0009-2012)》,签名结果为ASN.1编码:

SM2Signature::= SEQUENCE {

R INTEGER, --签名值的第一部分

S INTEGER --签名值的第二部分

}

4.2 验证

为了检验收到的消息M′及其数字签名(r′, s′),作为验证者的用户B应实现以下运算步骤:

B1:检验r′ ∈[1,n-1]是否成立,若不成立则验证不通过;

B2:检验s′ ∈[1,n-1]是否成立,若不成立则验证不通过;

B3:置M=ZA∥ M′;

B4:计算e′ = Hv(M),按规则将e′的数据类型转换为整数;

B5:按规则将r′、s′的数据类型转换为整数,计算t = (r′ + s′)
modn,若t = 0,则验证不通过;

B6:计算椭圆曲线点(x′1; y′1)=[s′]G +[t]PA

B7:按规则将x′1的数据类型转换为整数,计算R = (e′ + x′1)
modn,检验R=r′是否成立,若成立则验证通过;否则验证不通过。

X9.62 ECDSA的签名与验证过程:

签名:

1. Select a random or pseudorandom integerk, 1<=k<=n-1.

2. Compute [k]G = (x1,y1) and convert x1 toan integer x1`.

3. Compute r= x1 mod n. If r=0 then go tostep 1.

4. Compute k^-1 mod n.

5. Compute SHA-1(m) and convert this bitstring to an integer e.

6. Compute s = k^-1(e+dA*r) mod n. If s=0then go to step 1.

7. A's signature for the message m is(r,s).

验证:

1. Verify that r and s are integers in theinterval [1,n-1].

2. Compute SHA-1(m) and convert this bit stringto an integer e.

3. Compute w = s^-1 mod n€.

4. Compute u1= e*w mod n and u2= r*w modn€.

5. Compute X= [u1]G+[u2]PA.

6. If X=O, then reject the signature.

Otherwise, convert the x-coordinate x1

4.3 加密

设需要发送的消息为比特串M,klen为M的比特长度。

为了对明文M进行加密,作为加密者的用户A应实现以下运算步骤:

A1:用随机数发生器产生随机数k∈[1,n-1];

A2:计算椭圆曲线点C1=[k]G=(x1,y1),按本文本第1部分4.2.8和4.2.4给出的细节,将C1的数据类型转换为比特串;

A3:计算椭圆曲线点S=[h]PB,若S是无穷远点,则报错并退出;

A4:计算椭圆曲线点[k]PB=(x2,y2),按本文本第1部分4.2.5和4.2.4给出的细节,将坐标x2、y2的数据类型转换为比特串;

A5:计算t=KDF(x2∥ y2, klen),若t为全0比特串,则返回A1;

A6:计算C2 = M⊕ t;

A7:计算C3 = Hash(x2∥ M∥ y2);

A8:输出密文C = C1∥ C3∥ C2。

注:C1为‘04’开头,再加64字节的X和Y,C3为32字节的Hash值,C2和明文长度相同。即加密结果是原文长度+97字节。但按照《SM2密码算法使用规范(GM/T
0009-2012)》,签名结果为ASN.1编码:

SM2Cipher::= SEQUENCE{

XCoordinate INTEGER, --x分量

YCoordinate INTEGER, --y分量

HASH OCTECTSTRING SIZE(32), --杂凑值

CipherTextOCTECTSTRING--密文

}

4.4 解密

设klen为密文中C2的比特长度。

为了对密文C=C1∥ C3∥ C2进行解密,作为解密者的用户B应实现以下运算步骤:

B1:从C中取出比特串C1,按本文本第1部分4.2.3和4.2.9给出的细节,将C1的数据类型转换为椭圆曲线上的点,验证C1是否满足椭圆曲线方程,若不满足则报错并退出;

B2:计算椭圆曲线点S=[h]C1,若S是无穷远点,则报错并退出;

B3:计算[dB]C1=(x2,y2),按本文本第1部分4.2.5和4.2.4给出的细节,将坐标x2、y2的数据类型转换为比特串;

B4:计算t=KDF(x2∥ y2, klen),若t为全0比特串,则报错并退出;

B5:从C中取出比特串C2,计算M′ = C2⊕
t;

B6:计算u = Hash(x2∥ M′ ∥ y2),从C中取出比特串C3,若u
̸= C3,则报错并退出;

B7:输出明文M′。

5 加密消息语法

《SM2密码算法加密签名消息语法规范》(GM/T0010-2012)基本参照了PKCS#7的语法,然后再定义了一些国密算法的OID。令人奇怪的是,国密对data、signedData、envelopedData等还自定义了一套自己的OID,而不是沿用CMS已有的OID,实在看不出这样做有什么好处。

SM2密码算法加密签名消息语法规范:iso(1) member-body(2) cn(156) ccstc(10197) 6.1.4.2

PKCS#7 OID:iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs7(7)

6 数字证书

《基于SM2密码算法的数字证书格式规范》(GM/T0015-2012)定义的证书语法基本和RFC2459的X.509证书格式相同。

国密还定义了一些证书扩展如:个人身份标识码、个人社会保险号、企业工商注册号、企业组织机构代码、企业税号等。

6.1 签名算法

算法OID为:1.2.156.10197.1.501。即SM3withSM2。

参数为:NULL

6.2 主题公钥语法

参见本文“3.2 SM2公钥”对主题公钥的说明。

6.3 CA签名值

是ASN.1编码的SM2Signature结构,见本文“4.1签名”

7 开发接口

7.1 国密接口

国密接口有3个标准:《GMT0016智能密码钥匙密码应用接口规范》、《GMT0018密码设备应用接口规范》、《GMT0019通用密码服务接口规范》。搞不清楚为什么要分这么多标准。

7.2 PKCS#11

7.2.1 算法类型

pkcs11t.h已定义的ECC宏有:

#define CKM_EC_KEY_PAIR_GEN 0x00001040

#define CKM_ECDSA 0x00001041

……
自己扩展:

#define SM2_MYCA_DEFINED 0x92ca04

SM2密钥对产生

#define CKM_SM2_KEY_PAIR_GEN CKM_VENDOR_DEFINED+SM2_NETCA_DEFINED

SM2签名(传SM3 HASH值)

#define CKM_SM2DSA CKM_SM2_KEY_PAIR_GEN+1

SM2加密

#define CKM_SM2IES CKM_SM2_KEY_PAIR_GEN+2

7.2.2 密钥类型

#define CKK_EC 0x00000003

自己扩展:

#define CKK_SM2 CKK_VENDOR_DEFINED+SM2_MYCA_DEFINED



7.2.3 密钥模板

#define CKA_EC_PARAMS 0x00000180 (DER-encoding of an ANSI X9.62 Parameters value)

#define CKA_EC_POINT 0x00000181 (DER-encoding of ANSI X9.62 ECPoint value Q)

dA-->CKA_VALUE: (Biginteger)ANSI X9.62 private value d

PA(x,y)-->CKA_EC_POINT

7.3 CSP

Cryptographic Service Provider

CSP类型

在wincrypt.h有定义宏:

#define PROV_EC_ECDSA_FULL 16

#define PROV_EC_ECNRA_FULL 17

算法标识

在wincrypt.h有定义宏:

#define CALG_ECDH (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_ECDH)

#define CALG_ECMQV (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV)

#define CALG_ECDSA (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)



密钥结构

按《GMT0018密码设备应用接口规范》
#define ECCref_MAX_BITS 512

#define ECCref_MAX_LEN ((ECCref_MAX_BITS+7)/8)

typedefstruct ECCrefPublicKey_st

{

unsigned int bits;

unsigned char x[ECCref_MAX_LEN];

unsigned char y[ECCref_MAX_LEN];

}ECCrefPublicKey;

typedefstruct ECCrefPrivateKey_st

{

unsigned int bits;

unsigned char K[ECCref_MAX_LEN];

}ECCrefPrivateKey;

7.4 CNG

Cryptographic Next Generation

7.5 JCE

SunEC提供者只能支持X6.92的命名曲线,如果ECParameterSpec传递SM2的曲线参数,最终将报异常:“java.security.InvalidAlgorithmParameterException:Unsupported
curve”。如果用bouncycastle(“BC”), ECParameterSpec可以正常传递SM2的曲线参数,但由于SM2的签名与加密步骤都和X9.62/X9.63不同,所以出来的结果也不相同。需要自己在EC数学库的基础上实现SM2算法。

参考资料

《SM2椭圆曲线公钥密码算法第1部分:总则》(GM/T0003.1-2012),2012-03-21发布版本

《SM2椭圆曲线公钥密码算法第2部分:数字签名算法》(GM/T0003.2-2012),2012-03-21发布版本

《SM2椭圆曲线公钥密码算法第4部分:公钥加密算法》(GM/T0003.4-2012),2012-03-21发布版本

《SM2椭圆曲线公钥密码算法第5部分:参数定义》(GM/T0003.5-2012),2012-03-21发布版本

《SM2密码算法使用规范》(GM/T0009-2012),2012-11-22发布版本

《SM2密码算法加密签名消息语法规范》(GM/T0010-2012),2012-11-22发布版本

《基于SM2密码算法的数字证书格式规范》(GM/T0015-2012),2012-11-22发布版本











内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: