因为项目需要使用sm2加密算法,在网上找了很久没有找到一个很好的cpp支持项目,结果发现了这个项目,但是我找不到原链接了,所以只能自己发一下记录配置使用的过程。这个项目只支持c语言,cpp可能需要修改其中的加密算法
编译GMP生成静态库
先前往GNU MP的官网下载源码,官网地址为:https://gmplib.org/,下载源码安装包并解压,我使用的版本是gmp-6.1.1
cd gmp-6.1.1
# --prefix=后面的值为你要移植的位置,其他参数的含义见https://gmplib.org/manual/Build-Options
./configure --prefix=../../test/ --disable-shared --enable-fat --enable-cxx --with-pic CXXFLAGS="-g -O2"
# 这个版本的--prefix=好像只能加绝对路径,按照自己的环境来
make -j12
make check
# 若执行完make check没有报错,则
make install
# 如果想要重新配置编译,可以执行make distclean后重新配置编译
# 进入到安装的目录下,我的是test,删掉无用的文件
cd ../../test
rm -rf share
编译opencrypto
找不到这个项目的原始地址,其中其中主要有5个c文件和4个头文件,以及一个makefile,我会上传代码,并附上链接地址。不过这个makefile只能生成动态库,而我需要的是静态库,我将它换成了我自己写的。
# 定义静态库文件名
lib_name = libopc.a
# 源文件列表
sources = opcbn.c opcec.c opcrand.c opcsm2.c opcsm3.c
# 从源文件生成目标文件的规则
objects = $(sources:.c=.o)
# 设置编译器和选项
CC = gcc
CFLAGS = -O2 -fpic -lgmp
CFLAGS += -I../../test/include/ -I.
LDFLAGS = -L../../test/lib/
# 默认规则:将所有的源文件编译成目标文件
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 生成静态库的规则
$(lib_name): $(objects)
ar rcs $@ $(objects)
# 清理规则
clean:
rm -f $(lib_name) $(objects)
使用前记得将CFLAGS和LDFLAGS的值换为你自己的环境,就是上一步GMP的安装路径
编辑号makefile后,进行编译,生成静态库
make
# 将生成的静态库libopc.a,移动到gmp的安装目录下的lib文件夹下,记得修改移动目录
mv libopc.a ../../test/lib
# 将所有头文件移动到gmp的安装目录下的include文件夹下,记得修改移动目录
mv *.h ../../test/include
编写test.c测试sm2加密解密
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include "opc.h"
#include "opcsm2.h"
int main(int argc, char *argv[])
{
char cipherbuffer[512] = {0};
unsigned char plain[512];
char decrypt[256] = {0};
int decryptlen;
unsigned int plainlen = 32;
unsigned int tmplen;
int ret = 0;
opcec_t pubk;
opcbn_t prik;
opcbn_t rand;
opcec_group_t sm2group;
opcsm2_cipher *cipher = (opcsm2_cipher *)cipherbuffer;
opcsm2_signature sign;
/* you must be call this function first, init random state */
opcrand_init();
opcsm2_create_group(sm2group, OPC_SM2_256_NID);
opcec_init(pubk);
opcbn_init(prik);
opcbn_init(rand);
opcsm2_generate_key(sm2group, pubk, prik);
opcrand_generate_b(rand, plainlen);
opcbn_get_bin(plain, &tmplen, rand, 32);
opc_printf("---------------opc simple test--------------------\n", rand);
opc_printf("public key:X= %Zx, Y=%Zx\n", pubk->x, pubk->y);
opc_printf("private key = %Zx\n", prik);
opc_printf("plain = %Zx\n", rand);
opc_printf(" encrypt test\n", rand);
if ((ret = opcsm2_encrypt(sm2group, pubk, plain, plainlen, cipher)) != 0)
{
opc_printf("sm2 encrypt error ! ret = %d\n", ret);
return ret;
}
printf("cipher->XCoordinate = %s\n", cipher->XCoordinate);
printf("cipher->YCoordinate = %s\n", cipher->YCoordinate);
printf("cipher->HASH = %s\n", cipher->HASH);
printf("cipher->CipherLen = %d\n", cipher->CipherLen);
printf("cipher->Cipher = %s\n", cipher->Cipher);
opcbn_set_bin(rand, cipher->XCoordinate, 32);
opc_printf("cipher c1.x = %Zx\n", rand);
opcbn_set_bin(rand, cipher->YCoordinate, 32);
opc_printf("cipher c1.y = %Zx\n", rand);
opcbn_set_bin(rand, cipher->HASH, 32);
opc_printf("cipher c3 = %Zx\n", rand);
opcbn_set_bin(rand, cipher->Cipher, cipher->CipherLen);
opc_printf("cipher c2 = %Zx\n", rand);
if ((ret = opcsm2_decrypt(sm2group, cipher, prik, decrypt, &decryptlen)) < 0)
{
opc_printf("sm2 decrypt error ! ret = %d\n", ret);
return ret;
}
opcbn_set_bin(rand, decrypt, decryptlen);
opc_printf("decrypt = %Zx\n", rand);
if (decryptlen != plainlen || memcmp(decrypt, plain, plainlen))
{
opc_printf("sm2 decrypt data not equal!\n");
return ret;
}
opc_printf(" sign test\n", rand);
if ((ret = opcsm2_sign(sm2group, prik, plain, plainlen, &sign)) != 0)
{
opc_printf("sm2 sign error ! ret = %d!\n", ret);
return ret;
}
opcbn_set_bin(rand, sign.r, 32);
opc_printf("sign.r = %Zx\n", rand);
opcbn_set_bin(rand, sign.s, 32);
opc_printf("sign.s = %Zx\n", rand);
if ((ret = opcsm2_verify(sm2group, pubk, &sign, plain, plainlen)) != 0)
{
opc_printf("sm2 verify error ! ret = %d!\n", ret);
return ret;
}
opc_printf("verify success\n");
opc_printf("--------------------------------------------------\n", rand);
opc_printf("sm2 encrypt decrypt sign verify test success!\n");
opcec_clear_group(sm2group);
return 0;
} /* -------------- end function -------------- */
编写测试的makefile
CC = gcc
CFLAGS = -O2
CFLAGS += -I./include/
LDFLAGS += -L./lib/
all:
${CC} test.c -o test $(CFLAGS) $(LDFLAGS) -lopc -lgmp
clean:
rm test
完成之后
# 编译
make
# 运行
./test
评论区