美文网首页
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