二 SM2在PBOC认证中的使用
1 签名和验签的原理
前面提到根据系数的不同,ECC曲线可以有很多,SM2使用其中一种,这就表明它的曲线方程,以及前面说到的六个参量都是固定的。根据国密局给出的规范定义如下:
[cpp] view plaincopyprint?
1. y2=x3+ax+b 2.
3. p=FFFFFFFE FFFFFFFFFFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFF
FFF
4. a=FFFFFFFE FFFFFFFFFFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFF
FFC
5. b=28E9FA9E 9D9F5E344D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D9
40E93
6. n=FFFFFFFE FFFFFFFFFFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D5
4123
7. Gx=32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C
74C7
8. Gy=BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 21
39F0A0
这里容易引起一个误解,会认为参数都固定了,公私钥是不是只能有一对?当然不是,注意前面提到的K=kG的模型,K才是公钥,所以公钥其实是曲线在离散坐标系中,满足条件的一个曲线上的点。可以有很多个。另外, 从这几个参量可以获知PBOC 3.0的公钥长度都是256位。
基于这种离散椭圆曲线原理的SM2算法一般有三种用法,签名验签,加解密, 密钥交换。PBOC 3.0中的脱机数据认证只用到签名验签的功能。终端关心的是如何验签,卡片则要考虑如何实现生成签名。
2 基于openssl实现sm2
这里给出一个基于openssl的sm2实现, 如果不了解openssl,可以先搜索一下相关知识,这里不讲解。openssl已经实现ECC算法接口,也就是核心已经有了,实现sm2其实并不难,关键是理解它里面各种接口如何使用。下面就分析一个终端验签的sm2实现。另外需要说明这里给出的只是代码片段,仅供理解用。 函数接口
[cpp] view plaincopyprint?
1. int SM2_Verify(BYTE* Px,BYTE* Py, BYTE* DataIn,DWORD DataLen, BYTE* sigrs)
前两个参数是K的坐标值,也就是公钥。Datain和datalen分别是明文数据和其长度,最后一个参数是待验证的签名。
曲线的参数常量定义如下: [cpp] view plaincopyprint?
1. ////////////////////////////////////////////////////////////////
2. static const char *group_p =\
0000FFFFFFFFFFFFFFFF\
3. static const char *group_a =\
0000FFFFFFFFFFFFFFFC\
4. static const char *group_b =\
B8F92DDBCBD414D940E93\
5. static const char *group_Gx =\
60BE1715A4589334C74C7\
6. static const char *group_Gy =\
2A474002DF32E52139F0A0\
7. static const char *group_n = \
6052B53BBF40939D54123\
8. static const char *ENTL_ID =\9. #define SM2_KEY_LENGTH 32 //256位曲线 10. ////////////////////////////////////////////////////////////////
ENTL_ID是pboc规范中指定的用于SM3产生摘要的报文头数据。
[cpp] view plaincopyprint?
1. strcpy(szBuff, ENTL_ID); 2. strcat(szBuff,group_a); 3. strcat(szBuff,group_b); 4. strcat(szBuff,group_Gx); 5. strcat(szBuff,group_Gy);
6. AscToBcd(szDataForDigest,(unsigned char *)szBuff, nLen); 7.
8. …. 9.
10. SM3(szDataForDigest,nLen+SM2_KEY_LENGTH*2, digestZA); 11.
12. memcpy(szDataForDigest,digestZA, ECC_LENGTH);
13. memcpy(szDataForDigest+ECC_LENGTH,DataIn, DataLen); 14.
15. SM3(szDataForDigest,DataLen+ECC_LENGTH, digestH);
第一步,对上述数据用sm3做摘要,摘要的结果与数据拼接后再做摘要。
[cpp] view plaincopyprint?
1. 2. 3. 4. 5. 6. 7. 8.
p = BN_new(); a = BN_new(); b = BN_new();
group = EC_GROUP_new(EC_GFp_mont_method());
BN_hex2bn(&p, group_p)) BN_hex2bn(&a, group_a)) BN_hex2bn(&b, group_b))
这里是把定义的曲线常量转换成大数表式,这样才能使用openssl中的接口。
Group是ECC中的曲线组,它是ECC算法的核心,为什么这么说呢? 因为这个group里的所有字段就确定了曲线的所有信息, 后面会看到,这里只是用EC_GROUP_new生成一个空的group, 然后由p,a,b等参数来填充group, 再以这个group为基础去生成曲线上的点。
[cpp] view plaincopyprint?
1. if (!EC_GROUP_set_curve_GFp(group, p, a, b,ctx)) 2. {
3. gotoerr_process; 4. } 5.
6. P = EC_POINT_new(group); 7. Q = EC_POINT_new(group); 8. R = EC_POINT_new(group); 9. if (!P || !Q || !R) 10. {
11. gotoerr_process; 12. }
这一段就确定了group的所有信息,并且根据group生成三个曲线上的点(点一定在曲线上,这个很重要)。
[cpp] view plaincopyprint?
1. 6. gotoerr_process; 7. } 8. 9. //Gx 10. if(!BN_hex2bn(&x, group_Gx)) 11. { 12. gotoerr_process; 13. } 14. 15. if(!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) 16. { 17. gotoerr_process; 18. } 19. 20. if(!BN_hex2bn(&z, group_n)) 21. { 22. gotoerr_process; 23. } 24. if(!EC_GROUP_set_generator(group, P, z, BN_value_one())) 25. { 26. gotoerr_process; 27. } 28. 29. if(!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) 30. { 31. gotoerr_process; 32. } 这一段首先是设置n到group, n前面讲过,是曲线的阶。另外就是由G点坐标x,y确定点P,这里我其实也有点不太明白,G点坐标y本来就是已知的,为什么要再通过曲线变换表式生成y,是不是想要对比前面的group信息是否正确?只是为了校验? [cpp] view plaincopyprint? 1. if ((eckey = EC_KEY_new()) == NULL) 2. { 3. gotoerr_process; 4. } 5. if(EC_KEY_set_group(eckey, group) == 0) 6. { 7. gotoerr_process; 8. } 9. 10. EC_KEY_set_public_key(eckey, P); 11. if(!EC_KEY_check_key(eckey)) 搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新小学教育谈谈PBOC3.0中使用的国密SM2算法 (2)全文阅读和word下载服务。
相关推荐: