安装GmSSL3库并用VS编译CMake源码
准备工作
下载GmSSL3源码
从GmSSL官方GitHub仓库下载最新版本源码:
建议:
- 使用git克隆可以方便后续更新:git pull origin master
- 如需特定版本,可使用:git checkout tags/v3.0.0(替换为实际版本号)
安装必要工具
Visual Studio安装:
CMake安装:
Git安装(可选):
安装GmSSL3库
Windows系统安装
使用CMake生成VS工程
创建构建目录并配置:
mkdir build
cd build
cmake .. -G "Visual Studio 16 2019" -A x64 -DCMAKE_INSTALL_PREFIX=C:\\GmSSL
参数说明:
- -G:指定生成器版本("Visual Studio 16 2019"对应VS2019)
- -A:指定平台架构(x64或Win32)
- -DCMAKE_INSTALL_PREFIX:设置自定义安装路径
高级配置选项(可选):
cmake .. -D BUILD_SHARED_LIBS=ON -D ENABLE_SM3=ON -D ENABLE_SM4=ON -D ENABLE_SM9=OFF
编译安装
打开生成的解决方案:
编译步骤:
安装到系统:
Linux系统安装
配置编译选项
./config –prefix=/usr/local/gmssl \\
–openssldir=/usr/local/gmssl/ssl \\
enable-sm2 enable-sm3 enable-sm4
可选参数:
- shared:生成动态库
- -d:包含调试信息
- no-asm:禁用汇编优化(兼容性更好)
- no-shared:仅生成静态库
编译安装
编译:
make -j$(nproc) # 使用多核加速编译
测试(可选):
make test # 运行测试套件
安装:
sudo make install
配置环境变量:
echo 'export PATH=/usr/local/gmssl/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/gmssl/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
在VS项目中使用GmSSL3
配置项目属性
包含目录:
- 添加:$(GmSSL_INCLUDE_DIR) 或具体路径如 C:\\GmSSL\\include
- 在VS中:项目属性→C/C++→常规→附加包含目录
库目录:
- 添加:$(GmSSL_LIBRARY_DIR) 或具体路径如 C:\\GmSSL\\lib
- 在VS中:项目属性→链接器→常规→附加库目录
依赖库:
- 调试模式:gmssld.lib
- 发布模式:gmssl.lib
- 64位版本可能需要使用gmssl64.lib
- 在VS中:项目属性→链接器→输入→附加依赖项
运行时库:
- 确保项目属性→C/C++→代码生成→运行时库设置一致(如/MD或/MT)
- 应与GmSSL编译时的运行时库选项匹配
CMake集成示例
完整CMakeLists.txt示例:
cmake_minimum_required(VERSION 3.10)
project(MyGmSSLProject)
# 查找GmSSL库
find_package(GmSSL REQUIRED)
# 添加可执行文件
add_executable(sm2_test sm2_test.cpp)
# 包含目录
target_include_directories(sm2_test PRIVATE ${GmSSL_INCLUDE_DIR})
# 链接库
target_link_libraries(sm2_test ${GmSSL_LIBRARIES})
# 设置C++标准
set_target_properties(sm2_test PROPERTIES CXX_STANDARD 11)
# 复制DLL到输出目录(Windows动态库)
if(WIN32 AND BUILD_SHARED_LIBS)
add_custom_command(TARGET sm2_test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${GmSSL_LIBRARY_DIR}/gmssl.dll"
$<TARGET_FILE_DIR:sm2_test>)
endif()
常见问题解决
找不到GmSSL库
解决方案:
链接错误
常见错误及解决:
-
LNK2019:未解析的外部符号
- 检查是否遗漏了必要的库文件
- 确认函数声明与实现是否匹配
- 确保链接了正确的库版本(Debug/Release)
-
LNK2001:符号未定义
- 确保项目属性→链接器→输入是否包含所有必需库
- 检查是否使用了正确的命名空间
-
LNK4098:默认库冲突
- 确保项目属性→链接器→输入→忽略特定默认库设置正确
- 检查运行时库选项是否一致
API兼容性问题
GmSSL3与OpenSSL主要差异:
- 国密算法优先:SM2/SM3/SM4等
- 部分API前缀不同(如SM2_代替EC_)
- 新增国密专用API
兼容性建议:
// 传统OpenSSL方式
#include <openssl/evp.h>
// GmSSL推荐方式
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
测试示例
基本SM2测试程序
#include <stdio.h>
#include <string.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/rand.h>
int main() {
SM2_KEY sm2_key;
uint8_t msg[] = "Hello GmSSL!";
uint8_t dgst[32];
uint8_t sig[80];
size_t siglen;
// 初始化随机数生成器
rand_init();
// 生成密钥对
sm2_key_generate(&sm2_key);
printf("SM2 key generation successful!\\n");
printf("Public key (X): ");
for (int i = 0; i < 32; i++) printf("%02x", sm2_key.public_key.x[i]);
printf("\\nPublic key (Y): ");
for (int i = 0; i < 32; i++) printf("%02x", sm2_key.public_key.y[i]);
printf("\\n");
// 计算消息摘要
sm3_digest(msg, strlen((char *)msg), dgst);
printf("SM3 digest: ");
for (int i = 0; i < 32; i++) printf("%02x", dgst[i]);
printf("\\n");
// 签名
if (sm2_sign(&sm2_key, dgst, sig, &siglen) != 1) {
fprintf(stderr, "SM2 sign failed\\n");
return 1;
}
printf("Signature generated (%zu bytes): ", siglen);
for (size_t i = 0; i < siglen; i++) printf("%02x", sig[i]);
printf("\\n");
// 验证
if (sm2_verify(&sm2_key, dgst, sig, siglen) != 1) {
fprintf(stderr, "SM2 verify failed\\n");
return 1;
}
printf("Signature verified successfully\\n");
return 0;
}
运行测试
编译完成后:
在Windows上:
.\\build\\Release\\sm2_test.exe
在Linux上:
./sm2_test
预期输出应显示:





