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 预览版才有的,稳定版其实默认就带了,但需要通过配置暴露。
步骤(以 1.1.1l 为例)
- 下载源码包:
wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz - 解压并进入目录:
tar xzf openssl-1.1.1l.tar.gz && cd openssl-1.1.1l - 配置编译参数:
./config --prefix=/usr/local/openssl \ --openssldir=/usr/local/openssl/ssl \ shared \ enable-ec_nistp_64_gcc_128 \ enable-sm2 \ enable-sm3 \ enable-sm4 - 编译安装:
make -j$(nproc) && make install - 更新动态链接库:
echo "/usr/local/openssl/lib" | sudo tee /etc/ld.so.conf.d/openssl.conf && sudo ldconfig - 验证版本与国密支持:
/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 基本兼容,但添加了很多国密特有的特性。
FROM debian:bullseye-slim + 源码编译是最可控的方式。
编译安装步骤
- 从官方仓库拉代码:
git clone https://github.com/guanzhi/GmSSL.git - 进入目录:
cd GmSSL - 执行编译(GmSSL 不需要单独的 configure 参数):
./config --prefix=/usr/local/gmssl make -j$(nproc) make install - 设置环境变量:
export PATH=/usr/local/gmssl/bin:$PATH export LD_LIBRARY_PATH=/usr/local/gmssl/lib:$LD_LIBRARY_PATH - 验证:
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 -sm355e12e91650d2fec56ec74e1d3e4ddbfce2ef3a6588c2d2f9e3c0c034d3e0a0f - 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)
下面这张图梳理了从选择方案到验证的完整链路,方便你对照着做。
这张图把选择、安装、验证串起来了。你可以把它当作检查表,做完一步打个勾,不容易漏。
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 和哈希算法。
3.8 总结要点
环境搭建是后面所有操作的前提。记住这几条:
- 选择方案要“看人下菜碟”——已有 OpenSSL 则继续用,纯国密项目用 GmSSL。
- 安装务必注意版本和依赖,否则编译会卡住。
- 验证不能省,SM3、SM4、SM2 都要跑一遍。
- 容器化时,提前编译好,避免重复劳动。
下一部分咱们就要开始写国密算法的代码调用了,环境搭好才能跑得起来,对吧。