安装GmSSL3库后用VS编译CMake源码

安装GmSSL3库并用VS编译CMake源码

准备工作

下载GmSSL3源码

从GmSSL官方GitHub仓库下载最新版本源码:

  1. 访问官方仓库:https://github.com/guanzhi/GmSSL
  2. 点击"Code"按钮选择"Download ZIP"获取最新稳定版
  3. 或者使用git克隆命令:git clone https://github.com/guanzhi/GmSSL.git

建议:

  • 使用git克隆可以方便后续更新:git pull origin master
  • 如需特定版本,可使用:git checkout tags/v3.0.0(替换为实际版本号)

安装必要工具

Visual Studio安装:
  1. 推荐VS2019或VS2022社区版(免费)
  2. 安装时需勾选"使用C++的桌面开发"工作负载
  3. 确保包含Windows SDK(建议10.0.19041.0或更高)
  4. 可选安装"Windows 10 SDK (10.0.19041.0)"和"MSVC v142 - VS 2019 C++ x64/x86生成工具"
CMake安装:
  1. https://cmake.org/download/ 下载最新版本
  2. 安装时勾选"Add CMake to system PATH"
  3. 验证安装:cmake --version
  4. 建议版本:3.20或更高
Git安装(可选):
  1. https://git-scm.com/downloads 下载
  2. 安装时选择"Use Git from the Windows Command Prompt"
  3. 建议勾选"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
编译安装

打开生成的解决方案:

  1. 双击build目录下的GmSSL.sln文件
  2. 或通过VS菜单"文件"→"打开"→"项目/解决方案"

编译步骤:

  1. 在解决方案配置中选择"Release"或"Debug"
  2. 右键解决方案→"生成解决方案"(或按F7)
  3. 等待编译完成,检查输出窗口是否有错误

安装到系统:

  1. 在解决方案资源管理器中右键"INSTALL"项目
  2. 选择"生成"(需要管理员权限)
  3. 或使用命令: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库

解决方案:

  1. 设置环境变量:

    复制代码
    setx GmSSL_ROOT "C:\GmSSL"
  2. 或显式指定路径:

    复制代码
    cmake -DGmSSL_ROOT=C:\GmSSL ..
  3. 检查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

预期输出应显示:

  1. 密钥生成成功信息
  2. 公钥的X/Y坐标
  3. SM3摘要值
  4. 生成的签名及长度
  5. 签名验证成功信息
相关推荐
宇木灵9 小时前
C语言基础学习-二、运算符
c语言·开发语言·学习
想放学的刺客10 小时前
整理了120道单片机嵌入式面试题与答案,覆盖了硬件电路和C语言等核心领域。
c语言·c++·stm32·单片机·嵌入式硬件·mcu·51单片机
星辰徐哥11 小时前
C语言网络编程入门:socket编程、TCP/IP协议、客户端与服务器通信的实现
c语言·网络·tcp/ip
普通网友11 小时前
多协议网络库设计
开发语言·c++·算法
努力努力再努力wz11 小时前
【Linux网络系列】:TCP 的秩序与策略:揭秘传输层如何从不可靠的网络中构建绝对可靠的通信信道
java·linux·开发语言·数据结构·c++·python·算法
w8x9y0z111 小时前
大小端转换的隐藏陷阱:为什么你的网络数据传输总是出错?
c语言·网络编程·大小端·数据序列化
汉克老师12 小时前
GESP2024年3月认证C++二级( 第二部分判断题(1-10))
c++·循环结构·分支结构·gesp二级·gesp2级
daxi15012 小时前
C语言从入门到进阶——第9讲:函数递归
c语言·开发语言·c++·算法·蓝桥杯
Polaris北13 小时前
第二十七天打卡
开发语言·c++·算法