C语言实现SM4(基于GMSSL)

学习小白,有问题大牛可以指出来,本文主要是记录学习中遇到问题

环境:vs2019  gmssl 32位编译

1、首先新建项目

2、在VS的工程设置工程属性(参考连接https://blog.csdn.net/zhonghua_csdn/article/details/99011892

  1. 右击工程名 ——> 选择“属性”
  2. 在“VC++目录”——> “包含目录”中添加openSSL的include文件(在您安装openssl的文件下)
  3. 在“VC++目录”——> “库目录”中添加openSSL的lib文件(在您安装openssl的文件下)
  4. 在“链接器”——>“输入”——>“附加依赖项”中添加libssl.lib和libcrypto.lib(键盘输入);
  5. 将OpenSSL安装目录下bin文件夹中的“libcrypto-1_1-x64.dll”和“libssl-1_1-x64.dll”(名字和版本号可能不同)复制到你的项目工程目录下

3、引入已安装的gmssl:

第一步:将已有的gmssl下include中的openssl复制到自己项目的根目录下

第二步:在项目中新建openssl筛选器,并且将openssl文件夹中的文件复制到项目中

第三步: 修改C/C++ -> 附加包含目录添加:./;%(AdditionalIncludeDirectories)

4、编写demo(参考连接:https://blog.csdn.net/xueaiwen/article/details/103189443)此部分只有加密的验证

#include "openssl/sms4.h"
#include <iostream>

#define GETCH() getchar()
#define PUTCH(ch) 

int SM4_ECB(int Flag, unsigned char* Key, unsigned char* In, unsigned char* Out, unsigned int Len);
int AddPadding(unsigned char* In, int inLen, unsigned char* Out, int* outLen);

/*
sm4 ecb模式加密/解密
Flag 运算标志,0为加密,1为解密。
Key sm4算法密钥。
In sm4算法ecb运算输入数据。
Out sm4算法ecb计算得到密文。
Len ecb明文/密文长度。
*/
int SM4_ECB(int Flag, unsigned char* Key, unsigned char* In, unsigned char* Out, unsigned int Len)
{
    int i;
    int Ret;
    int PadLen;
    unsigned char Pad[256];//可以根据实际情况malloc需要的空间
    sms4_key_t key;
    if (!Flag)
    {
        memset(Pad, 0, sizeof(Pad));
        Ret = AddPadding(In, Len, Pad, &PadLen);//检查是否是16倍数,不是补全
        if (Ret < 0)
        {
            return -2;
        }
        sms4_set_encrypt_key(&key, Key);

        for (i = 0; i < PadLen / 16; i++)
        {
            sms4_encrypt(Pad + i * 16, Out + i * 16, &key);
        }
    }
    else
    {
        sms4_set_decrypt_key(&key, Key);
        for (i = 0; i < Len / 16; i++)
        {
            sms4_encrypt(In + i * 16, Out + i * 16, &key);
        }
    }
    return 0;
}
int AddPadding(unsigned char* In, int inLen, unsigned char* Out, int* outLen)
{
    int PaddingLen = -1;
    char tmpPadding[16];

    if (inLen <= 0)
    {
        return -1;
    }
    *outLen = 0;
    PaddingLen = 16 - (inLen % 16 == 0 ? 16 : inLen % 16);
    if (PaddingLen == 0)
    {
        memcpy(Out, In, inLen);
        *outLen = inLen;
        return 1;
    }
    memset(tmpPadding, 0, 16);
    memset(tmpPadding, PaddingLen, PaddingLen);

    memcpy(Out, In, inLen);
    *outLen += inLen;

    memcpy(Out + *outLen, tmpPadding, PaddingLen);
    *outLen += PaddingLen;
    return 0;
}

int main()
{
    int rv;
    int flag = 0;
    unsigned char pbKeyValue[16] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
    unsigned char pbPlainText[16] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
    unsigned char pbCipherText[16] = { 0x68,0x1e,0xdf,0x34,0xd2,0x06,0x96,0x5e,0x86,0xb3,0xe9,0x4f,0x53,0x6e,0x42,0x46 };
    unsigned char pbDataOut[16] = { 0 };

    unsigned int len = sizeof(pbPlainText);
    //flag=0,调用加密方法,将加密结果取出与标准加密结果对比
    rv = SM4_ECB(flag, pbKeyValue, pbPlainText, pbDataOut, len);
    if (len != sizeof(pbCipherText) || memcmp(pbDataOut, pbCipherText, len) != 0)
    {
        printf("\n");
        printf("sm4-ecb encrypt is error!\n");
        printf("\n按任意键继续...");
        GETCH();
    }
    else
    {
        printf("\n");
        printf("sm4-ecb encrypt is ok!\n");
        printf("\n按任意键继续...");
        GETCH();
    }
}

5、编译遇到错误

解决方法:右键属性—c/c++—预处理器

6、调试报错

解决方法:此时需要将dll 和lib都copy到本地项目的debug目录下

7、调试程序成功

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值