项目中需要用到sm2加密,在网上搜索了一下相关的库,发现只有openssl和gmssl这两个库可以用,于是基于gmssl库做了封装,gmssl的版本是:GmSSL 2.5.4 - OpenSSL 1.1.0d 19 Jun 2019
搞这个库的确要费不少功夫,现在分享出来给需要的人。目前我是用在linux环境中,因此编译成linux动态库,并且屏蔽相关库的头文件和符号,只暴露sm2加解密相关的接口符号,gmssl库通过静态库的方式引用。
关于sm2加密有几个比较重要的参数,第一个是椭圆曲线参数,第二个是密文编码方式,第三个是哈希算法,目前我们用的都是固定的参数,所以封装的时候没有提供参数选择这些功能,需要的可以自行扩展。下面的sm2加密相关参数为:使用默认的椭圆曲线参数(sm2p256v1),ASN.1/DER编码方式(C1|C3|C2编码方式) ,哈希(杂凑)算法使用sm3
一些初学者可能还不大懂怎么引用外部库,我把我自己的工程上传到github上了,可以作为参考,gmssl库我已经编译好,生成的是静态库,但是gmssl库的编译其实还是应该用自己的机器去编译的,因为自己拿我编译好的静态库去用的话,不同的linux版本有可能不兼容。gmssl库文件我也放在该工程下了,可以不用去官网找,文件为:GmSSL-master.zip。 github地址:qingfeng1992/gmutil: 基于gmssl加密库封装sm2加解密方法 (github.com)
可以直接使用git clone git@github.com:qingfeng1992/gmutil.git 拉取代码
下载下来后请先看README.txt后再操作
gmutil.h头文件:
#ifndef __GM_UTIL_H__
#define __GM_UTIL_H__
#include <string>
using namespace std;
#ifdef _WIN32
#define UNIX_EXPORT
#else
#define UNIX_EXPORT __attribute__((visibility("default")))
#endif
// namespace GM
//{
// 错误码
enum EGMErrorCode
{
GM_UTIL_CODE_OK = 0,
GM_UTIL_CODE_CREATE_EV_KEY_FAILED, // 密钥解析失败
GM_UTIL_CODE_SM2_ENCRYPT_FAILED, // SM2加密失败
GM_UTIL_CODE_SM2_DECRYPT_FAILED, // SM2解密失败
GM_UTIL_CODE_NOT_SM2P256V1, // 不是默认的sm2p256v1椭圆曲线参数
GM_UTIL_CODE_INIT_BIO_FAILED, // 初始化BIO失败
GM_UTIL_CODE_CIPHER_TEXT_TO_BIO_FAILED, // 加密数据存储到BIO失败
GM_UTIL_CODE_BIO_DATA_TO_MEM_FAILED, // BIO数据转存到缓冲区失败
GM_UTIL_CODE_BIO_DATA_TO_CIPHER_TEXT_FAILED, // BIO数据转成Ciphertext结构失败
};
extern "C"
{
// 从文件中读入公钥/私钥数据到string中,失败返回空字符串
UNIX_EXPORT string GmReadKeyFromFile(string strFileName);
/**
* @brief sm2加密,使用默认的椭圆曲线参数(NID_sm2p256v1),ASN.1/DER编码方式(C1|C3|C2编码方式) ,哈希(杂凑)算法使用sm3
* @param strPubKey 公钥数据
* @param strIn 需要加密的数据
* @param strCiphertext 密文,加密后的密文不是可见字符
* @return 返回GM_UTIL_ERR_OK表示加密成功,否则失败,具体见EGMErrorCode定义
*/
UNIX_EXPORT int GmSm2Encrypt(string strPubKey, const string &strIn, string &strCiphertext);
/**
* @brief sm2解密,使用默认的椭