OpenSSL SM4加密 CMake工程链接失败
在项目中遇到需要使用sm4加密的功能,同事在一个动态库(C库)里面使用了openssl中的sm4加密,成功编译并功能正常。我也需要在项目(QT程序)中同样的方式使用sm4加密与之通讯,结果我卡在链接的位置无法编程完成,下面是摘出来的demo:
#include <stdio.h>
#include <memory.h>
#include <malloc.h>
#include <openssl/ossl_typ.h>
#include <openssl/aes.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/sm2.h>
#include <openssl/sm4.h>
#include <openssl/evp.h>
#include <openssl/ec.h>#define PKCS1_HEADER "-----BEGIN RSA PUBLIC KEY-----"
#define PKCS8_HEADER "-----BEGIN PUBLIC KEY-----"enum EncryptType {ET_RSA = 0,ET_SM2
};int main(int argc, char *argv[])
{const int tokenSize = 256;const int padding = AES_BLOCK_SIZE - tokenSize % AES_BLOCK_SIZE;const int blockCount = 256;const int bufferSize = blockCount * AES_BLOCK_SIZE;char *tokenBuffer = new char[static_cast<size_t>(bufferSize)];memset(tokenBuffer, padding, static_cast<size_t>(bufferSize));char *ciphertext = new char[static_cast<size_t>(bufferSize)];memset(ciphertext, 0, static_cast<size_t>(bufferSize));char *symmetricKey = new char[static_cast<size_t>(bufferSize)];SM4_KEY sm4;AES_KEY aes;int ret = 0;EncryptType m_encryptType = ET_SM2;if (ET_SM2 == m_encryptType) {SM4_set_key(reinterpret_cast<uint8_t *>(symmetricKey), &sm4);} else {AES_set_encrypt_key(reinterpret_cast<unsigned char *>(symmetricKey), strlen(symmetricKey), &aes);}if (ret < 0) {delete[] tokenBuffer;delete[] ciphertext;return 0;}unsigned char *iv = new unsigned char[AES_BLOCK_SIZE];memset(iv, 0, AES_BLOCK_SIZE);if (ET_SM2 == m_encryptType) {SM4_encrypt(reinterpret_cast<uint8_t *>(tokenBuffer), reinterpret_cast<uint8_t *>(ciphertext), &sm4);} else {AES_cbc_encrypt(reinterpret_cast<unsigned char *>(tokenBuffer), reinterpret_cast<unsigned char *>(ciphertext), static_cast<size_t>(bufferSize), &aes, iv, AES_ENCRYPT);}delete[] ciphertext;delete[] tokenBuffer;delete[] iv;return 0;
}
报错如下:
$ gcc -o libtest.so test.cpp -lstdc++ -lcrypto /usr/bin/ld: /tmp/ccR5x6An.o: in function `main':
test.cpp:(.text+0xb0): undefined reference to `SM4_set_key(unsigned char const*, SM4_KEY_st*)'
/usr/bin/ld: test.cpp:(.text+0x14f): undefined reference to `SM4_encrypt(unsigned char const*, unsigned char*, SM4_KEY_st const*)'
collect2: error: ld returned 1 exit status
库肯定是link成功了 ,因为其他的函数都没有报错,只有sm4的程序报了。我也是百思不得其解,我尝试使用同事编译过的项目,发现,加上-shared就能编译通过
gcc -shared -o libtest.so test.cpp -lstdc++ -lcrypto
很离谱,我的QT界面项目当然不能加这个参数。
我就仔细看了下sm4.h,忽然发现头文件中没有用extern "C"修复函数!
C++在编译的过程中会改变函数的名称,与C语言的规则不一致,这样在链接的时候就无法找到C语言对应的函数,从而导致undefined reference!
在需要使用源文件中将原来的include 用extern "C"修饰就可以编译通过了。
#ifdef __cplusplus
extern "C" {
#endif
#include <openssl/sm2.h>
#include <openssl/sm4.h>
#ifdef __cplusplus
}
#endif
CMakeLists
需要注意的几个地方:
# cmake > 3.12 详见https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
find_package(OpenSSL REQUIRED) target_link_libraries(${ProjectName} PRIVATE${OPENSSL_CRYPTO_LIBRARY}
)
总结
在C++中使用C库的时候,如果遇到链接问题,要注意C库的头文件中是否使用extern "C"修饰了函数。
OpenSSL SM4加密 CMake工程链接失败相关推荐
- 初识CMake,如何编写一个CMake工程(上)
如何编写一个CMake工程 笔者想分享CMake工程的原因? 1 接触CMake 1.1 认识CMake被广泛的使用? 1.2 了解CMake运行流程 1.3 Make和Makefile是什么关系? ...
- 初识CMake,如何编写一个CMake工程(下)
如何编写一个CMake工程 上文分析了针对一个源文件.多个源文件.多个目录的情况 1 CMake自定义编译选项Demo4 1.1 效果展示 2 CMake安装(make install)与测试(mak ...
- c++/c SM4加密解密算法代码实现
#include <openssl/sms4.h>int main(void) {//加密参数初始化sms4_key_t sms4_key_enc;unsigned char *plain ...
- Linux下CMake工程中gtestgmock的安装与使用
Linux下CMake工程中gtest&gmock的安装与使用 gtest和gmock是什么和功能以及用法可参考以下两篇文章,都相当给力! gtest <玩转Google开源C++单元测 ...
- 使用加密锁加密Unity工程插件源码
使用加密锁加密Unity工程插件源码 最近在unity3D中开发了一款插件,需要卖给客户,但是公司需要隐藏插件的源码,而且保证客户只有指定的电脑才能使用该插件开发!针对这个问题,分为两个步骤:1.隐藏 ...
- 安卓和php接口数据传输加密,安卓与PHP间的RSA(openssl)交互加密的坑
这几天在写一个安卓的RSA公钥加密算法,用于跟PHP后台接口进行交互.在实践过程中发现了几个坑.其中我的公钥和私钥都是通过openssl生成的pem格式. 遇到的坑: 1.通过java的RSA公钥加密 ...
- C#.NET 国密SM4加密解密 CBC ECB 2种模式
注意点: 1.加密时,明文转 byte[] 时,不要用 Encoding.Default,一定要指定编码,如:UTF-8. 解密时,解出的 byte[] 转 string 同样要指定相同的编码. 2. ...
- python SM4加密
import binascii #导入国密算法sm4包 from gmssl import sm4 def sm4_encode(key, data): """ ...
- 解决“libboost_regex-vc120-mt-gd-1_59.lib“链接失败问题
在VS2013 64位+Boost 64 位 v1.59编程中,有时会遇到*.lib链接失败的问题.通常该问题有2种情况: A)电脑里没有安装Boost v1.59,或者安装的版本不对 ...
最新文章
- Centos7 编译安装 Nginx、MariaDB、PHP
- java class 生成对象_Java反射机制(创建Class对象的三种方式)
- UA MATH571B 试验设计 QE练习题 不使用代码分析试验结果I
- 【Java】15 输入输出
- zipaligin不是内部或外部命令,也不是可运行的程序
- 安卓开发中的USB转串口通讯
- Linux基础入门学习笔记之二
- pil 图像最大值_第97天:图像库 PIL(二)
- 七、线性表的链式存储结构
- python大学教程 pdf_『Python核心编程(第二版)PDF和Python基础教程(第二版)PDF?』python大学教程pdf下载...
- linux系统安装java环境_linux系统java环境配置
- 动态爬虫之qzone空间自动秒赞 - qq空间自动点赞
- VMWARE 之 分布式网络交换机
- 婚纱摄影、影楼、照相馆流量制造工具预约系统之种草社区
- 宠物商店——三层架构
- 手机屏幕驱动板HDMI调光触摸旋转说明Fondar
- PCL中采样一致性算法
- CSS常见选择器的用法
- SVG中年月日相关的表达式
- JAVA JDK8的介绍下载和安装(附网盘地址)