安装GmSSL3库并用VS编译CMake源码
准备工作
下载GmSSL3源码
从GmSSL官方GitHub仓库下载最新版本源码:
- 访问官方仓库:https://github.com/guanzhi/GmSSL
- 点击"Code"按钮选择"Download ZIP"获取最新稳定版
- 或者使用git克隆命令:
git clone https://github.com/guanzhi/GmSSL.git
建议:
- 使用git克隆可以方便后续更新:
git pull origin master - 如需特定版本,可使用:
git checkout tags/v3.0.0(替换为实际版本号)
安装必要工具
Visual Studio安装:
- 推荐VS2019或VS2022社区版(免费)
- 安装时需勾选"使用C++的桌面开发"工作负载
- 确保包含Windows SDK(建议10.0.19041.0或更高)
- 可选安装"Windows 10 SDK (10.0.19041.0)"和"MSVC v142 - VS 2019 C++ x64/x86生成工具"
CMake安装:
- 从https://cmake.org/download/ 下载最新版本
- 安装时勾选"Add CMake to system PATH"
- 验证安装:
cmake --version - 建议版本:3.20或更高
Git安装(可选):
- 从https://git-scm.com/downloads 下载
- 安装时选择"Use Git from the Windows Command Prompt"
- 建议勾选"Git LFS (Large File Support)"选项
安装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
编译安装
打开生成的解决方案:
- 双击build目录下的GmSSL.sln文件
- 或通过VS菜单"文件"→"打开"→"项目/解决方案"
编译步骤:
- 在解决方案配置中选择"Release"或"Debug"
- 右键解决方案→"生成解决方案"(或按F7)
- 等待编译完成,检查输出窗口是否有错误
安装到系统:
- 在解决方案资源管理器中右键"INSTALL"项目
- 选择"生成"(需要管理员权限)
- 或使用命令:
cmake --build . --target install --config Release
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库
解决方案:
-
设置环境变量:
setx GmSSL_ROOT "C:\GmSSL" -
或显式指定路径:
cmake -DGmSSL_ROOT=C:\GmSSL .. -
检查CMake查找路径是否正确:
find_package(GmSSL REQUIRED HINTS "C:/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
预期输出应显示:
- 密钥生成成功信息
- 公钥的X/Y坐标
- SM3摘要值
- 生成的签名及长度
- 签名验证成功信息