0%

SM9

SM9属于标识密码算法的一种。传统的非对称算法,比如RSA的公钥分发时,因为公钥只是一串无意义的随机数,需要使用PKI系统来给公钥添加额外的身份认证。这样在传输密钥的时候,就需要带上一整套证书的东西,比较重。标识密码算法中,直接使用身份标识来作为用户公钥,比较轻量。

SM9包含4个部分算法:1. 数字签名算法,2. 密钥交换协议,3. 密钥封装机制,4.公钥加密算法。

1. SM9中的一些概念

  • 标识: identity,可唯一确定一个实体身份的信息,应该由实体无法否认的信息组成,比如电子邮箱、身份证号、电话号码等。
  • 密钥生成中心:key generation center; KGC,负责选择系统参数,生成主密钥,产生用户私钥的可信机构,相当于PKI体系中的CA。
  • 主密钥:master key,由KGC生成,主私钥由随机数发生器产生,主公钥由主私钥结合系统参数产生。KGC秘密保存主私钥,公开主公钥。KGC使用主私钥和用户标识产生用户私钥,用户标识相当于用户公钥。另外,密钥分签名系统密钥和加密系统密钥,数字签名算法属于签名系统,使用签名主密钥;密钥交换协议、密钥封装机制和公钥加密算法属于加密系统,使用加密主密钥。
  • 系统参数:SM9基于ECC算法,系统参数包含一系列参数,以确定SM9的运算规则和范围。由KGC提供,用户选择使用。

2. 数字签名算法

2.1. 相关密钥的产生

相关密钥 说明 产生方式
ks 签名主私钥 KGC产生随机数作为签名主私钥。KGC秘密保存
Ppub-s 签名主公钥 KGC根据(ks)计算得出签名主公钥。KGC公开
hid 函数标识符 KGC选择并公开一个字节表示的签名私钥生成函数标识符hid
ID-A 用户A标识 A的邮箱,身份证,电话号码等,相当于用户A的公钥
ds-A 用户A的签名私钥 KGC根据(ID-A,hid,ks)计算出A的签名私钥

2.2. 辅助函数

  1. 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
  2. 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
  3. 密码函数H2(Z, n): 输入比特串Z和整数n, 输出一个整数h2。内部会用到Hv()
  4. 随机数发生器

2.3. 签名

输入:

  1. 系统参数
  2. 签名主公钥 Ppub-s
  3. 待签名消息 M
  4. 签名密钥 ds-A

输出:

  1. 签名值(h, S)

2.5. 验签

输入:

  1. 系统参数
  2. 签名主公钥 Ppub-s
  3. 算法识别符 hid
  4. 用户标识(公钥) ID-A
  5. 待验签消息 M’
  6. 数字签名 (h’, S’)

输出:

  1. 验签通过或不通过

2.6. 小结

  • 签名验签都需要签名主公钥,签名需要用户私钥,验签需要用户公钥(用户标识)

3. 密钥交换协议

3.1. 相关密钥的产生

相关密钥 说明 产生方式
ke 加密主私钥 KGC产生随机数作为加密主私钥。KGC秘密保存
Ppub-e 加密主公钥 KGC根据(ke)计算得出加密主公钥。KGC公开
hid 函数标识符 KGC选择并公开一个字节表示的签名私钥生成函数标识符hid
ID-A 用户A标识 A的邮箱,身份证,电话号码等,相当于用户A的公钥
de-A 用户A的加密私钥 KGC根据(ID-A,hid,ke)计算出A的加密私钥
ID-B 用户B标识 B的邮箱,身份证,电话号码等,相当于用户B的公钥
de-B 用户B的加密私钥 KGC根据(ID-B,hid,ke)计算出B的加密私钥

3.2. 辅助函数

  1. 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
  2. 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
  3. 密码函数H2(Z, n): 输入比特串Z和整数n, 输出一个整数h2。内部会用到Hv()
  4. 密码派生函数KDF(Z, klen): 输入比特串Z和要获得的密钥数据的比特长度klen,输出长度为klen比特位的比特串K。内部会用到Hv()
  5. 随机数发生器

3.3. 密钥交换协议过程

用户A和B通过交换一些公开数据,协商获得密钥数据长度为klen比特的共有密钥参数(相当于预主密钥)。

用户A:
A1. 生成随机数 r-A
A2. 根据(r-A, ID-B, hid, Ppub-e)计算得到 R-A
A3. 将 R-A 发送给 B

用户B:
B1. 验证 R-A 是否有效,无效则协商失败;有效则根据(R-A, de-B, Ppub-e, r-B)计算出 g1, g2, g3
B2. 生成随机数 r-B
B3. 根据(r-B, ID-A, hid, Ppub-e)计算得到 R-B
B4. 计算 SK-B = KDF(ID-A || ID-B || R-A || R-B || g1 || g2 || g3, klen)
B5. (可选)计算 S-B = Hash(0x82 || g1 || Hash(g2 || g3 || ID-A || ID-B || R-A || R-B))
B6. 将 R-B,(可选)S-B发送给 A

用户A:
A4. 验证 R-B 是否有效,无效则协商失败;有效则根据(R-B, de-A, Ppub-e, r-A)计算出g1’, g2’, g3’
A5. (可选) 计算 S1 = Hash(0x82 || g1’ || Hash(g2’ || g3’ || ID-A || ID-B || R-A || RB)),并校验 S1 == S-B,不成立则从B到A的密钥确认失败
A6. 计算 SK-A = KDF(ID-A || ID-B || R-A || R-B || g1’ || g2’ || g3’, klen)
A7. (可选)计算 S-A = Hash(0x83 || g1’ || Hash(g2’ || g3’ || ID-A || ID-B || R-A || R-B)),将 S-A 发送给 B

用户B:
B7: (可选)计算 S2 = Hash(0x83 || g1 || Hash(g2 || g3 || ID-A || ID-B || R-A || R-B)), 并检验 S2==S-A,若不成立,则从A到B的密钥确认失败

最后协商出的共有密钥是 SK-A 和 SK-B

3.4. 小结

用户A输入的参数:

  1. 系统参数
  2. 加密主公钥 Ppub-e
  3. 算法识别符 hid
  4. 加密私钥 de-A
  5. 双方公钥,标识 ID-A, ID-B

用户A收到的参数:

  1. R-B
  2. (可选)S-B

用户B输入的参数:

  1. 系统参数
  2. 加密主公钥 Ppub-e
  3. 算法识别符 hid
  4. 加密私钥 de-B
  5. 双方公钥,标识 ID-A, ID-B

用户B收到的参数:

  1. R-A
  2. (可选)S-A

4. 密钥封装机制

将比特长度klen的密钥封装后给B,B解封拿到相应密钥。

4.1. 相关密钥的产生

相关密钥 说明 产生方式
ke 加密主私钥 KGC产生随机数作为加密主私钥。KGC秘密保存
Ppub-e 加密主公钥 KGC根据(ke)计算得出加密主公钥。KGC公开
hid 函数标识符 KGC选择并公开一个字节表示的签名私钥生成函数标识符hid
ID-B 用户B标识 B的邮箱,身份证,电话号码等,相当于用户B的公钥
de-B 用户B的加密私钥 KGC根据(ID-B,hid,ke)计算出B的加密私钥

4.2. 辅助函数

  1. 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
  2. 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
  3. 密码派生函数KDF(Z, klen): 输入比特串Z和要获得的密钥数据的比特长度klen,输出长度为klen比特位的比特串K。内部会用到Hv()
  4. 随机数发生器

4.3. 密钥封装算法

输入:

  1. 系统参数
  2. 加密主公钥 Ppub-e
  3. 识别符 hid
  4. 标识符 ID-B

输出:

  1. (K, C), K是被封装的密钥,C是封装密文

4.4. 密钥解封算法

输入:

  1. 系统参数
  2. 封装密文 C
  3. 标识 ID-B
  4. 加密私钥 de-B

输出:

  1. 密钥 K’ 或报错

5. 公钥加密算法

要发送的消息为M,mlen是M的比特长度,K1_Len是分组密码算法中密钥K1的比特长度,K2_len是MAC(K2, Z)函数中密钥K2的比特长度。

5.1. 相关密钥的产生

相关密钥 说明 产生方式
ke 加密主私钥 KGC产生随机数作为加密主私钥。KGC秘密保存
Ppub-e 加密主公钥 KGC根据(ke)计算得出加密主公钥。KGC公开
hid 函数标识符 KGC选择并公开一个字节表示的签名私钥生成函数标识符hid
ID-B 用户B标识 B的邮箱,身份证,电话号码等,相当于用户B的公钥
de-B 用户B的加密私钥 KGC根据(ID-B,hid,ke)计算出B的加密私钥

5.2. 辅助函数

  1. 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
  2. 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
  3. 密码函数H2(Z, n): 输入比特串Z和整数n, 输出一个整数h2。内部会用到Hv()
  4. 密码派生函数KDF(Z, klen): 输入比特串Z和要获得的密钥数据的比特长度klen,输出长度为klen比特位的比特串K。内部会用到Hv()
  5. 分组密码算法,包括加密算法 Enc(K1, m) 和解密算法 Dec(K1, c)。如 SM4
  6. 消息认证码函数MAC(K2, Z), 防止消息数据Z被非法篡改,使用密钥K2,产生认证码Z。内部会用到Hv()
  7. 随机数发生器

5.3. 加密算法

输入:

  1. 系统参数
  2. 加密主公钥 Ppub-e
  3. 识别符 hid
  4. 长度为 mlen比特的消息 M
  5. 标识 ID-B

输出:

  1. 密文 C=C1 || C3 || C2

5.3. 解密算法

输入:

  1. 系统参数
  2. 密文 C=C1 || C3 || C2
  3. 标识 ID-B
  4. 加密私钥 de-B

输出:

  1. 明文 M’ 或报错

5.4. 小结

A使用B的加密公钥 ID-B 和加密主公钥 Ppub-e 加密消息,B使用私钥 de-B 解密数据。

6. 参考

  1. GMT0044-2016 SM9标识密码算法