跳到主要内容

GB/T 35276-2017 信息安全技术 SM2 密码算法使用规范

返回主题目录 · 官方来源

来源:GB/T 35276-2017 国家标准详情;发布日期:2017-12-29;实施日期:2018-07-01。 官方在线预览截图 SHA-256:650e7cbda75e8f948421c2304a1d71cfae7143426287229b3ad364f2311d60ae。 转写说明:依据官方在线预览的 11 页图像逐页识别并校核,省略封面、目录、页眉和页脚,合并跨页段落;公式和 ASN.1 定义按页面重新整理为可连续阅读的文本。7.2 中的 SEQENCE 为原页拼写,疑似原文笔误。正式引用请核对官方原页。

前言​

本标准按照 GB/T 1.1—2009 给出的规则起草。

请注意本文件的某些内容可能涉及专利。本文件的发布机构不承担识别这些专利的责任。

本标准由全国信息安全标准化技术委员会(SAC/TC 260)提出并归口。

本标准起草单位:北京海泰方圆科技股份有限公司、卫士通信息产业股份有限公司、无锡江南信息安全工程技术中心、兴唐通信科技股份有限公司、山东得安信息技术有限公司、上海格尔软件股份有限公司。

本标准主要起草人:刘平、蒋红宇、柳增寿、李元正、徐强、谭武征、孔凡玉、王妮娜。

引言​

SM2 椭圆曲线公钥密码算法(以下简称 SM2)是由 GB/T 32918 给出的一组非对称算法,其中包括 SM2-1 椭圆曲线数字签名算法、SM2-2 椭圆曲线密钥协商协议、SM2-3 椭圆曲线加密算法。

本标准的目标是保证 SM2 使用的正确性,为 SM2 密码算法的使用制定统一的数据格式和使用方法。

本标准中涉及的 SM3 算法是指 GB/T 32905 给出的一种密码杂凑算法。

本标准仅从算法应用的角度给出 SM2 密码算法的使用说明,不涉及 SM2 密码算法的具体编制细节。

1 范围​

本标准规定了 SM2 密码算法的使用方法,以及密钥、加密与签名等的数据格式。

本标准适用于 SM2 密码算法的使用,以及支持 SM2 密码算法的设备和系统的研发和检测。

2 规范性引用文件​

下列文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅注日期的版本适用于本文件。凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件。

  • GB/T 32905—2016 信息安全技术 SM3 密码杂凑算法
  • GB/T 32918.1—2016 信息安全技术 SM2 椭圆曲线公钥密码算法 第 1 部分:总则
  • GB/T 32918.2—2016 信息安全技术 SM2 椭圆曲线公钥密码算法 第 2 部分:数字签名算法
  • GB/T 32918.3—2016 信息安全技术 SM2 椭圆曲线公钥密码算法 第 3 部分:密钥交换协议
  • GB/T 32918.4—2016 信息安全技术 SM2 椭圆曲线公钥密码算法 第 4 部分:公钥加密算法
  • GB/T 32918.5—2017 信息安全技术 SM2 椭圆曲线公钥密码算法 第 5 部分:参数定义

3 术语和定义​

下列术语和定义适用于本文件。

3.1 算法标识 algorithm identifier​

用于标明算法机制的数字化信息。

3.2 SM2 密码算法 SM2 cryptographic algorithm​

由 GB/T 32918(所有部分)定义的一种算法。

3.3 SM3 密码算法 SM3 cryptographic algorithm​

由 GB/T 32905—2016 定义的一种算法。

4 缩略语​

下列缩略语适用于本文件。

  • ECB:电码本模式(Electronics Code Book)
  • ECC:椭圆曲线密码算法(Elliptic Curve Cryptography)

5 SM2 的密钥对​

5.1 SM2 私钥​

SM2 私钥是大于 1 且小于 n-1 的整数(n 为 SM2 算法的阶,其值见 GB/T 32918.5—2017 的第 2 章),简记为 k,长度为 256 位。

5.2 SM2 公钥​

SM2 公钥是 SM2 曲线上的一个点,由横坐标和纵坐标两个分量来表示,记为(x,y),简记为 Q,每个分量的长度为 256 位。

6 数据转换​

6.1 位串到 8 位字节串的转换​

位串长度若不是 8 的整数倍,需先在它的左边补 0,以保证它的长度为 8 的倍数,然后构造 8 位字节串,转换过程如下:

输入:一个长度为 blen 的位串 B。

输出:一个长度为 mlen 的字节串 M,其中 mlen 的取值为(blen+7)/8 的整数部分。

动作:将位串 B=B_0 B_1 …… B_{blen-1} 转换到 8 位字节串 M=M_0 M_1 …… M_{mlen-1},采用如下方法:从 1≤i≤mlen-1,设置:

M_i = B_{blen-8-8(mlen-1-i)} B_{blen-7-8(mlen-1-i)} …… B_{blen-1-8(mlen-1-i)}

对于 M₀,最左边 8-blen%8 位设置为 0,右边设置为 B_0 B_1 …… B_{8-8(mlen)+blen-1}。

输出 M。

6.2 8 位字节串到位串的转换​

8 位字节串到位串转换过程如下:

输入:一个长度为 mlen 的 8 位字节串 M。

输出:一个长度为 blen=(8×mlen) 的位串 B。

动作:将 8 位字节串 M=M_0 M_1 …… M_{mlen-1} 转换到位串 B=B_0 B_1 …… B_{blen-1},采用如下方法:从 0≤i≤mlen-1,设置:

B_{8i} B_{8i+1} …… B_{8i+7} = M_i

输出 B。

6.3 整数到 8 位字节串的转换​

一个整数转换为 8 位字节串,基本方法是将其先使用二进制表达,然后把结果位串再转换为 8 位字节串。以下是转换流程:

输入:一个非负整数 x,期望的 8 位字节串长度 mlen。基本限制为:2^{8(mlen)}>x。

输出:一个长度为 mlen 的 8 位字节串 M。

动作:将基于 2^8=256 的 x 值 x=x_{mlen-1}2^{8(mlen-1)}+x_{mlen-2}2^{8(mlen-2)}+……+x_1 2^8+x_0 转换为一个 8 位字节串 M=M_0 M_1 …… M_{mlen-1},采用如下方法:从 0≤i≤mlen-1,设置:

M_i = x_{mlen-1-i}

输出 M。

6.4 8 位字节串到整数的转换​

可以简单地把 8 位字节串看成以 256 为基表示的整数,转换过程如下:

输入:一个长度 mlen 的 8 位字节串 M。

输出:一个整数 x。

动作:将一个 8 位字节串 M=M_0 M_1 …… M_{mlen-1} 转换为整数 x,方法如下:将 Mᵢ 看作 [0~255] 中的一个整数。

x = Σ_{i=0}^{mlen-1} 2^{8(mlen-1-i)} M_i

输出 x。

7 数据格式​

7.1 密钥数据格式​

SM2 算法私钥数据格式的 ASN.1 定义为:

SM2PrivateKey ::= INTEGER

SM2 算法公钥数据格式的 ASN.1 定义为:

SM2PublicKey ::= BIT STRING

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

7.2 加密数据格式​

SM2 算法加密后的数据格式的 ASN.1 定义为:

SM2Cipher ::= SEQENCE {
XCoordinate INTEGER, -- x 分量
YCoordinate INTEGER, -- y 分量
HASH OCTET STRING SIZE(32), -- 杂凑值
CipherText OCTET STRING -- 密文
}

其中,HASH 为使用 SM3 算法对明文数据运算得到的杂凑值,其长度固定为 256 位。CipherText 是与明文对应的密文。

7.3 签名数据格式​

SM2 算法签名数据格式的 ASN.1 定义为:

SM2Signature ::= SEQUENCE {
R INTEGER, -- 签名值的第一部分
S INTEGER -- 签名值的第二部分
}

7.4 密钥对保护数据格式​

在 SM2 密钥对传递时,需要对 SM2 密钥对进行加密保护。具体的保护方法:

a)产生一个对称密钥;

b)按对称密码算法标识指定的算法对 SM2 私钥进行加密,得到私钥的密文。若对称算法为分组算法,则其运算模式为 ECB;

c)使用外部 SM2 公钥加密对称密钥得到对称密钥密文;

d)将私钥密文、对称密钥密文封装到密钥对保护数据中。

SM2 密钥对的保护数据格式的 ASN.1 定义:

SM2EnvelopedKey ::= SEQUENCE {
symAlgID AlgorithmIdentifier, -- 对称密码算法标识
symEncryptedKey SM2Cipher, -- 对称密钥密文
Sm2PublicKey SM2PublicKey, -- SM2 公钥
Sm2EncryptedPrivateKey BIT STRING -- SM2 私钥密文
}

8 预处理​

8.1 预处理 1​

预处理 1 是指使用签名方的用户身份标识和签名方公钥,通过运算得到 Z 值的过程。Z 值用于预处理 2,也用于 SM2 密钥协商协议。

输入:ID,字节串,用户身份标识;Q,SM2PublicKey,用户的公钥。

输出:Z,字节串,预处理 1 的输出。

计算公式为:

Z = SM3(ENTL || ID || a || b || x_G || y_G || x_A || y_A)

式中:ENTL 为由 2 个字节表示的 ID 的比特长度;ID 为用户身份标识;a、b 为系统曲线参数;x_G、y_G 为基点;x_A、y_A 为用户的公钥。

详细的计算过程见 GB/T 32918.2—2016 的 5.5 和 GB/T 32905—2016 的第 5 章。

8.2 预处理 2​

预处理 2 是指使用 Z 值和待签名消息,通过 SM3 运算得到杂凑值 H 的过程。杂凑值 H 用于 SM2 数字签名。

输入:Z,字节串,预处理 2 的输入;M,字节串,待签名消息。

输出:H,字节串,杂凑值。

计算公式为:

H = SM3(Z || M)

详细的计算过程见 GB/T 32918.2—2016 的 6.1 和 GB/T 32905—2016 的第 5 章。

9 计算过程​

9.1 生成密钥​

SM2 密钥生成是指生成 SM2 算法的密钥对的过程,该密钥对包括私钥和与之对应的公钥。

输入:无。

输出:k,SM2PrivateKey,SM2 私钥;Q,SM2PublicKey,SM2 公钥。

详细的计算过程见 GB/T 32918.1—2016 的 6.1。

9.2 加密​

SM2 加密是指使用指定公开密钥对明文进行特定的加密计算,生成相应密文的过程。该密文只能由该指定公开密钥对应的私钥解密。

输入:Q,SM2PublicKey,SM2 公钥;m,字节串,待加密的明文数据。

输出:c,SM2Cipher,密文。

其中:输出参数 c 的格式由本规范 7.2 中定义;输出参数 c 的 XCoordinate、YCoordinate 为随机产生的公钥的 x 分量和 y 分量;输出参数 c 中的 HASH 的计算公式为:

HASH = SM3(x || m || y)

式中,x、y 为 Q 的 x 分量和 y 分量;输出参数 c 中 CipherText 为加密密文,其长度等于明文的长度。

详细的计算过程见 GB/T 32918.4—2016 的 6.1。

9.3 解密​

SM2 解密是指使用指定私钥对密文进行解密计算,还原对应明文的过程。

输入:d,SM2PrivateKey,SM2 私钥;c,SM2Cipher,密文。

输出:m,字节串,与密文对应的明文。m 为 SM2Cipher 经过解密运算得到的明文,该明文的长度与输入参数 c 中 CipherText 的长度相同。

详细的计算过程见 GB/T 32918.4—2016 的 7.1。

9.4 数字签名​

SM2 签名是指使用预处理 2 的结果和签名者私钥,通过签名计算得到签名结果的过程。

输入:d,SM2PrivateKey,签名者私钥;H,字节串,预处理 2 的结果。

输出:sign,SM2Signature,签名值。

详细的计算过程见 GB/T 32918.2—2016 的 6.1。

9.5 签名验证​

SM2 签名验证是指使用预处理 2 的结果、签名值和签名者的公钥,通过验签计算确定签名是否通过验证的过程。

输入:H,字节串,预处理 2 的结果;sign,SM2Signature,签名值;Q,PublicKey,签名者的公钥。

输出:为“真”表示“验证通过”,为“假”表示“验证不通过”。

详细的计算过程见 GB/T 32918.2—2016 的 7.1。

9.6 密钥协商​

密钥协商是在两个用户之间建立一个共享秘密密钥的协商过程,通过这种方式能够确定一个共享秘密密钥的值。

设密钥协商双方为 A、B,双方的密钥对分别为(d_A,Q_A)和(d_B,Q_B),双方需要获得的密钥数据的比特长度为 klen。密钥协商协议分为两个阶段。

第一阶段:产生临时密钥对。

用户 A:调用生成密钥算法产生临时密钥对(r_A,R_A),将 R_A 和用户 A 的用户身份标识 ID_A 发送给用户 B。

用户 B:调用生成密钥算法产生临时密钥对(r_B,R_B),将 R_B 和用户 B 的用户身份标识 ID_B 发送给用户 A。

第二阶段:计算共享秘密密钥。

用户 A 的输入参数:

参数类型说明
Q_ASM2PublicKey用户 A 的公钥
Q_BSM2PublicKey用户 B 的公钥
R_ASM2PublicKey用户 A 的临时公钥
ID_AOCTET STRING用户 A 的用户身份标识
R_BSM2PublicKey用户 B 的临时公钥
ID_BOCTET STRING用户 B 的用户身份标识
d_ASM2PrivateKey用户 A 的私钥
r_ASM2PrivateKey用户 A 的临时私钥
klenINTEGER需要输出的密钥数据的比特长度

输出参数:K,OCTET STRING,位长为 klen 的密钥数据。

步骤:

a)用 ID_A 和 Q_A 作为输入参数,调用预处理 1 得到 Z_A;

b)用 ID_B 和 Q_B 作为输入参数,调用预处理 1 得到 Z_B;

c)以 klen、Z_A、Z_B、d_A、r_A、R_A、Q_B、R_B 为输入参数,进行运算得到 K。

用户 B 的输入参数:

参数类型说明
Q_BSM2PublicKey用户 B 的公钥
Q_ASM2PublicKey用户 A 的公钥
R_BSM2PublicKey用户 B 的临时公钥
ID_BOCTET STRING用户 B 的用户身份标识
R_ASM2PublicKey用户 A 的临时公钥
ID_AOCTET STRING用户 A 的用户身份标识
d_BSM2PrivateKey用户 B 的私钥
r_BSM2PrivateKey用户 B 的临时私钥
klenINTEGER需要输出的密钥数据的比特长度

输出参数:K,OCTET STRING,位长为 klen 的密钥数据。

步骤:

a)用 ID_A 和 Q_A 作为输入参数,调用预处理 1 得到 Z_A;

b)用 ID_B 和 Q_B 作为输入参数,调用预处理 1 得到 Z_B;

c)以 klen、Z_A、Z_B、d_B、r_B、R_B、Q_A、R_A 为输入参数,进行运算得到 K。

详细的计算过程见 GB/T 32918.3—2016 的 6.1。

10 用户身份标识 ID 的默认值​

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

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