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. 辅助函数
- 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
- 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
- 密码函数H2(Z, n): 输入比特串Z和整数n, 输出一个整数h2。内部会用到Hv()
- 随机数发生器
2.3. 签名
输入:
- 系统参数
- 签名主公钥 Ppub-s
- 待签名消息 M
- 签名密钥 ds-A
输出:
- 签名值(h, S)
2.5. 验签
输入:
- 系统参数
- 签名主公钥 Ppub-s
- 算法识别符 hid
- 用户标识(公钥) ID-A
- 待验签消息 M’
- 数字签名 (h’, S’)
输出:
- 验签通过或不通过
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. 辅助函数
- 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
- 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
- 密码函数H2(Z, n): 输入比特串Z和整数n, 输出一个整数h2。内部会用到Hv()
- 密码派生函数KDF(Z, klen): 输入比特串Z和要获得的密钥数据的比特长度klen,输出长度为klen比特位的比特串K。内部会用到Hv()
- 随机数发生器
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输入的参数:
- 系统参数
- 加密主公钥 Ppub-e
- 算法识别符 hid
- 加密私钥 de-A
- 双方公钥,标识 ID-A, ID-B
用户A收到的参数:
- R-B
- (可选)S-B
用户B输入的参数:
- 系统参数
- 加密主公钥 Ppub-e
- 算法识别符 hid
- 加密私钥 de-B
- 双方公钥,标识 ID-A, ID-B
用户B收到的参数:
- R-A
- (可选)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. 辅助函数
- 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
- 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
- 密码派生函数KDF(Z, klen): 输入比特串Z和要获得的密钥数据的比特长度klen,输出长度为klen比特位的比特串K。内部会用到Hv()
- 随机数发生器
4.3. 密钥封装算法
输入:
- 系统参数
- 加密主公钥 Ppub-e
- 识别符 hid
- 标识符 ID-B
输出:
- (K, C), K是被封装的密钥,C是封装密文
4.4. 密钥解封算法
输入:
- 系统参数
- 封装密文 C
- 标识 ID-B
- 加密私钥 de-B
输出:
- 密钥 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. 辅助函数
- 密码杂凑函数Hv(M): 就是hash函数,输出长度为v比特的杂凑值,比如SM3
- 密码函数H1(Z, n): 输入比特串Z和整数n, 输出一个整数h1。内部会用到Hv()
- 密码函数H2(Z, n): 输入比特串Z和整数n, 输出一个整数h2。内部会用到Hv()
- 密码派生函数KDF(Z, klen): 输入比特串Z和要获得的密钥数据的比特长度klen,输出长度为klen比特位的比特串K。内部会用到Hv()
- 分组密码算法,包括加密算法 Enc(K1, m) 和解密算法 Dec(K1, c)。如 SM4
- 消息认证码函数MAC(K2, Z), 防止消息数据Z被非法篡改,使用密钥K2,产生认证码Z。内部会用到Hv()
- 随机数发生器
5.3. 加密算法
输入:
- 系统参数
- 加密主公钥 Ppub-e
- 识别符 hid
- 长度为 mlen比特的消息 M
- 标识 ID-B
输出:
- 密文 C=C1 || C3 || C2
5.3. 解密算法
输入:
- 系统参数
- 密文 C=C1 || C3 || C2
- 标识 ID-B
- 加密私钥 de-B
输出:
- 明文 M’ 或报错
5.4. 小结
A使用B的加密公钥 ID-B 和加密主公钥 Ppub-e 加密消息,B使用私钥 de-B 解密数据。
6. 参考
- GMT0044-2016 SM9标识密码算法