3. 国密算法开发环境搭建:安装 OpenSSL / GmSSL

搞国密开发,第一步就是把环境搭起来。这步看着简单,可坑也不少。我最早接触国密时,直接拿系统自带的 OpenSSL 就开干,结果 SM2 签名死活不对,查了半天才反应过来——官方 OpenSSL 1.1.1 虽然支持 SM2/SM3/SM4,但默认不启用,而且参数配置跟 GmSSL 差别挺大。

所以这一章,咱们就专门梳理一下 OpenSSL(带国密扩展)和 GmSSL 的安装流程、差异对比,以及我踩过的那些坑。

3.1 选哪个?OpenSSL 还是 GmSSL?

先说结论:如果只做国密算法调用,并且你的项目已经依赖 OpenSSL,直接在 OpenSSL 1.1.1+ 里启用国密是最省事的。 但如果你需要完整的国密证书链解析、自定义 OID 或者做硬件加密机对接,GmSSL 会更顺手。

我个人的习惯是这样:

  • 生产环境已有 OpenSSL → 升级到 1.1.1 或 3.x,启用国密模块。
  • 全新国密项目 → 用 GmSSL(国密标准实现更严格)。
  • 容器化场景 → 两种都可以,但推荐把编译好的二进制直接塞进镜像,避免二次编译。

3.2 安装 OpenSSL(带国密支持)

官方 OpenSSL 1.1.1 在编译时需要加 enable-ec enable-sm2 enable-sm3 enable-sm4 这些参数。注意,enable-sm2 是 1.1.1 预览版才有的,稳定版其实默认就带了,但需要通过配置暴露。

⚠ 警告: 如果你用的是 OpenSSL 1.1.0 以下版本,就别指望自带的国密了,老老实实升级。

步骤(以 1.1.1l 为例)

  1. 下载源码包:wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz
  2. 解压并进入目录:tar xzf openssl-1.1.1l.tar.gz && cd openssl-1.1.1l
  3. 配置编译参数:
    ./config --prefix=/usr/local/openssl \
              --openssldir=/usr/local/openssl/ssl \
              shared \
              enable-ec_nistp_64_gcc_128 \
              enable-sm2 \
              enable-sm3 \
              enable-sm4
  4. 编译安装:make -j$(nproc) && make install
  5. 更新动态链接库:echo "/usr/local/openssl/lib" | sudo tee /etc/ld.so.conf.d/openssl.conf && sudo ldconfig
  6. 验证版本与国密支持:
    /usr/local/openssl/bin/openssl version
    /usr/local/openssl/bin/openssl list -cipher-algorithms | grep SM4
    /usr/local/openssl/bin/openssl list -digest-commands | grep SM3

输出里能看到 SM4 和 SM3 才算安装成功。我记得第一次在 CentOS 7 上编译,死活找不到 SM2 算法,后来发现是因为没装 perl-IPC-Cmd 依赖,编译脚本没跑通。所以提前装好依赖:yum install -y perl-IPC-Cmd perl-devel。

3.3 安装 GmSSL

GmSSL 是专门为国密定制的分支,接口和 OpenSSL 基本兼容,但添加了很多国密特有的特性。

💡 小技巧: GmSSL 的 Docker 官方镜像很少更新,建议自己写 Dockerfile 编译。FROM debian:bullseye-slim + 源码编译是最可控的方式。

编译安装步骤

  1. 从官方仓库拉代码:git clone https://github.com/guanzhi/GmSSL.git
  2. 进入目录:cd GmSSL
  3. 执行编译(GmSSL 不需要单独的 configure 参数):
    ./config --prefix=/usr/local/gmssl
    make -j$(nproc)
    make install
  4. 设置环境变量:
    export PATH=/usr/local/gmssl/bin:$PATH
    export LD_LIBRARY_PATH=/usr/local/gmssl/lib:$LD_LIBRARY_PATH
  5. 验证:
    gmssl version
    gmssl sm2keygen -help

这里有个小坑:GmSSL 编译时默认会启用 enable-ec 等,但如果系统缺少 libpthread 头文件,编译会报错。我当时在 Alpine 上碰到过,后来换成了 Debian 基础镜像才搞定。

3.4 两种方案对比

对比项 OpenSSL(国密扩展) GmSSL
维护方 OpenSSL 社区 国密标准工作组
国密支持完整性 SM2/3/4,但缺少部分证书 OID 完整支持 SM2/3/4/9,国密证书链
与系统 OpenSSL 共存 容易冲突,建议指定路径 独立命名空间,基本无冲突
容器化体积 约 30MB(编译后) 约 40MB
坑点 SM2 签名默认不验证 hash 长度 默认使用国密标准曲线,与 OpenSSL 参数不同

3.5 环境验证清单

安装完别急着写代码,先跑几个命令确认一切正常。我通常会按这个清单检查:

  • SM3 哈希计算:
    echo -n "test" | openssl dgst -sm3
    
    输出应为 55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a6588c2d2f9e3c0c034d3e0a0f
  • SM4 加密解密:
    openssl enc -sm4-ecb -K 0123456789abcdeffedcba9876543210 -in test.txt -out test.enc
    openssl enc -d -sm4-ecb -K 0123456789abcdeffedcba9876543210 -in test.enc
  • SM2 密钥对生成:
    openssl ecparam -genkey -name SM2 -out sm2_private.pem
    openssl ec -in sm2_private.pem -pubout -out sm2_public.pem

关键节点: 如果你发现 SM2 密钥生成报错 unknown curve name (SM2),说明编译时没有开启 SM2 曲线支持。重新编译 OpenSSL 加上 enable-sm2 即可。

3.6 整体安装流程(SVG)

下面这张图梳理了从选择方案到验证的完整链路,方便你对照着做。

国密开发环境搭建流程 选择方案 OpenSSL 国密扩展 GmSSL 独立安装 下载 & 编译配置 Git 克隆 & 编译 安装 & 更新链接库 安装 & 设环境变量 环境验证清单 继续下一章

这张图把选择、安装、验证串起来了。你可以把它当作检查表,做完一步打个勾,不容易漏。

3.7 常见问题与避坑

这部分是我实际踩过的,你可能会遇到:

  • 编译 OpenSSL 时缺少 Perl 模块: 报错 Can't locate IPC/Cmd.pm。解决方法:yum install perl-IPC-Cmd 或 apt install perl-ipc-cmd。
  • 系统 OpenSSL 与新安装冲突: 不要把新编译的 OpenSSL 覆盖系统路径,建议用 --prefix 指定独立目录,并在用到的地方用路径。
  • GmSSL 编译报错 undefined reference to 'EC_GROUP_new_curve_GF2m': 这是缺少 libec 库导致的,需要先安装 libec 开发包。
  • SM2 签名验签在 OpenSSL 与 GmSSL 之间不通用: 因为它们使用的默认曲线参数和哈希算法略有差异。跨库调用时一定要指定相同的 OID 和哈希算法。
💡 节省时间的建议: 如果你的团队已经用 Docker,建议直接封装一个国密基础镜像,把 OpenSSL 或 GmSSL 编译进去,以后新项目直接 FROM 这个镜像,省掉重复编译的时间。我所在的团队就是这么干的,效果很好。

3.8 总结要点

环境搭建是后面所有操作的前提。记住这几条:

  • 选择方案要“看人下菜碟”——已有 OpenSSL 则继续用,纯国密项目用 GmSSL。
  • 安装务必注意版本和依赖,否则编译会卡住。
  • 验证不能省,SM3、SM4、SM2 都要跑一遍。
  • 容器化时,提前编译好,避免重复劳动。

下一部分咱们就要开始写国密算法的代码调用了,环境搭好才能跑得起来,对吧。