美文网首页
SM2国密算法封装 C++

SM2国密算法封装 C++

作者: 布灵不灵的丙丙 | 来源:发表于2020-03-07 10:35 被阅读0次

    背景介绍:

    项目应某客户要求,需要对密码等安全属性要求高的字段进行加密保护与传输,并且必须使用国密(SM2, SM3, SM4)加密算法,项目是C++语言开发,需要与java前端进行调试,本人以前也没有接触过加密算法,因此查询了很多资料,走了很多弯路,现在将自己整理的关于SM2算法一些东西发出来,希望可以对有需要的小伙伴有所帮助。

    场景介绍:

    假设,给了你一个hex编码的公钥,然后给了一个待加密字段,如何加密,或者说给了一个hex编码的私钥,给了一个hex编码的待解密字段,如何解密?我的文章就围绕这个给您解答。

    特别感谢

    感谢两位博主的文章及其开源项目,通过他们的源码学到了很多东西,以下为链接:

    https://github.com/greendow/SM2-encrypt-and-decrypt
    https://github.com/NEWPLAN/SMx
    

    前置介绍

    文档

    • 文档请参考官方文档,但是官方示例为C1C2C3加密模式,
    • 需要使用到openssl,所以我windows安装了openssl来进行调试,安装版本为openssl-1.1.1b,安装教程可以参考:https://blog.csdn.net/weixin_41642793/article/details/90407107

    公钥及私钥介绍:

    • 公钥:公钥是一个65字节长的字符数组,用于加密使用
    • 组成:04 || X || Y,X和Y是公钥的坐标点,长度各为32位,这个需要理解
    • 私钥:私钥是一个由32字节长度组成的字节数组,用于解密使用

    加密模式

    • 本次采用C1C3C2加密模式,下边是一个需要用到的宏定义:
    #define BUFFER_APPEND_STRING(buffer1, pos1, length1, x) \
        memcpy(&buffer1[pos1], x, length1); \
        pos1 = pos1 + length1
    

    流程讲解

    加密流程

    • 收到一个hex编码的公钥040471008F95FFD0E1F8AD1CC886E09402F45CC8A935DAE145B88B3768C80BF6E18879AAE458FEFBBB7114F6D9F11192860359FA50B403293F00592A6061B59F8F
    • 收到一个待加密字段I have a dream!
    • 经过加密获取到C1,C2, C3的值
    • 接下来调用这个函数,便可以获取到加密后的字段,但是这里是内存字节,通常我们将它转成hex编码的字符串:
    void setMessage(const unsigned char* c1,
        const unsigned char* c2,
        const unsigned char* c3,
        const unsigned char* messagg,
        const unsigned int msgByteLen)
    {
        int pos1 = 0;
        BUFFER_APPEND_STRING(messagg, pos1, 1 + 64
            , c1);
        BUFFER_APPEND_STRING(messagg, pos1, 32
            , c3);
        BUFFER_APPEND_STRING(messagg, pos1, msgByteLen
            , c2);
    
        DEFINE_SHOW_STRING(messagg, pos1);
    }
    

    解密过程:

    • 输入hex编码私钥:3A2C8E1BB7B922FC7CB8E32FE7EFB6C1F3C0BF3ABAFE5560552BF67DA55BFD4B
    • 输入待解密字段:0404EBFC718E8D1798620432268E77FEB6415E2EDE0E073C0F4F640ECD2E149A73E858F9D81E5430A57B36DAAB8F950A3C64E6EE6A63094D99283AFF767E124DF096AEA0772D8FE093BFB72FD6C5AF50007A052EA7CA6F1FF2D2C258B84647BBDB821D028B7A3E21D17CCFF4A34ECD19
    • 首先进行hexdecode,然后通过下边的这个函数我们便可以获取到C1,C2, C3的值
    void getMessage(unsigned char* c1,
        unsigned char* c2,
        unsigned char* c3,
        const unsigned char* messagg,
        const unsigned int msgByteLen)
    {
        int pos1 = 0;
        int pos2 = 0;
        BUFFER_APPEND_STRING(c1, pos1, 1 + 64
            , &messagg[pos2]);
        DEFINE_SHOW_STRING(c1, pos1);
        pos2 = pos2 + pos1;
        pos1 = 0;
        BUFFER_APPEND_STRING(c3, pos1, 32
            , &messagg[pos2]);
        DEFINE_SHOW_STRING(c3, 32);
        pos2 = pos2 + pos1;
        pos1 = 0;
        BUFFER_APPEND_STRING(c2, pos1, (msgByteLen - pos2)
            , &messagg[pos2]);
        DEFINE_SHOW_STRING(c2, msgByteLen - pos2);
    
    }
    
    • 然后我们调用解密接口,即可获取到解密后的字段。

    未完待续,稍后整理将代码开源

    相关文章

      网友评论

          本文标题:SM2国密算法封装 C++

          本文链接:https://www.haomeiwen.com/subject/kbhqdhtx.html