失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 基于国密SM3算法(openssl接口)密钥派生函数KDF的实现

基于国密SM3算法(openssl接口)密钥派生函数KDF的实现

时间:2020-09-26 03:25:49

相关推荐

基于国密SM3算法(openssl接口)密钥派生函数KDF的实现

前言

最近项目需要使用KDF生成秘钥,对比国密标准(GB_T 32918.4-)及网络资料,发现确实没有让我满意的, 自己结合标准和大佬:Heidlyn的帖子《国密SM2算法密钥派生函数KDF的实现》动手写了一个并成功通过标准下面的测试用例,个人认为更加通俗易懂。现分享给大家

代码

//KDF函数的实现基于GB_T32918_4- 5.3.4章《密钥派生函数》实现//函数功能:KDF秘钥派生函数//输入参数: Z-用于计算的比特串//Zlen -Z的字节数//klen -需要获得秘钥数据的字节长度//输出参数: K-长度为klen的秘钥数据比特串K(这里设置为128位)void my_KDF(const unsigned char* Z, const unsigned int Zlen, const unsigned int Klen, unsigned char* K){unsigned int ct = 1;//计数器unsigned char cCt[4] = {0 }; //计数器的内存表示值unsigned char *pData = new unsigned char[Zlen + 4];unsigned char cdgst[32] = {0 }; //摘要int nDgst = 32; //摘要长度 单位:字节unsigned int hash_len;//sm3输出串长度 int index = (Klen + 32) / 32;//需要计算的次数,这里+32表示至少要进行一次循环if (Z == NULL || Klen <= 0 || Zlen < 0 || K == NULL){return -1;}//初始化空间memset(pData, 0, Zlen + 4);//复制比特串Zmemcpy(pData, Z, Zlen);for (size_t i = 0; i < index ; i++){//内存表示计数器{cCt[0] = (ct >> 24) & 0xFF;cCt[1] = (ct >> 16) & 0xFF;cCt[2] = (ct >> 8) & 0xFF;cCt[3] = (ct) & 0xFF;}//拼接比特串memcpy(pData + Zlen, cCt, 4);//sm3函数处理,这里使用openssl内的EVP_SM3接口处理SM3_HASH(pData, Zlen + 4, cdgst, &hash_len);//最后一次计算,根据klen/32是否整除,若未整除,则截取最后一次hash的值if (i == index - 1){if (Klen % 32 != 0){nDgst = (Klen) % 32;}}memcpy(K + 32 * i, cdgst, nDgst);ct++;}return ;}

测试部分

测试用例截取(GB_T 32918.4-)标准中的部分涉及到KDF的计算,下面是截图

图里的用例是将坐标x2和y2拼接后进行KDF运算,其中生成消息比特长度为152

我将截图里的测试用例文字显示出,方便各位测试:

坐标x2: 64D20D27D0632957F8028C1E024F6B02EDF23102A566C932AE8BD613A8E865FE

坐标y2: 58D225ECA784AE300A81A2D48281A828E1CEDF11C4219099840265375077BF78

应 得: 006E30DAE231B071DFAD8AA379E90264491603

测试结果:

上述代码中使用到的SM3函数为openssl中的EVP_SM3接口,我自己做了简单封装,可以直接调用EVP_SM3使用。

如果觉得《基于国密SM3算法(openssl接口)密钥派生函数KDF的实现》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。