在 2020 年疫情封城期间,我在家无事可做,于是选择开发国密浏览器,具体来说,是为 Firefox 浏览器增加国密支持。选择 Firefox 而非更流行的 Chromium 浏览器,是因为课题的要求。
Firefox 采用了 Gecko 引擎,网络协议栈则使用 NSS。我的主要任务是在 NSS 上实现国密算法,参考了 GmSSL 的实现方法。
整个开发过程进展顺利,当时我能够专心阅读相关 RFC 和国密标准文档,这与当时封闭在家,哪儿也去不了有关。
遗憾的是,最终未能做出产品,但我记录并发表了开发过程和研究成果在公众号上。国密开发属于小众领域,文章阅读量很低,基本上每篇不到百人阅读。
2023年,公司武汉分部关闭,我不得不重新找工作。在求职期间,我整理了有关国密开发的文章,形成了《详解国密算法》专栏,并选择设为付费订阅,主要是为了看看读者是否真的对这个专题感兴趣。
出乎意料的是,一年多来吸引了十几名订阅者。随着信息国产化需求增加,越来越多产品要求支持国密,这使得我之前的总结和记录仍有一定的价值。
最近有人询问国密相关问题,但距离我最后研究国密已有四年时间,相关实现细节已经忘记了。
更尴尬的是,我当时的文章是以 GmSSL 为基础编写的,然而这几年 GmSSL 架构经历了大幅调整,导致代码结构和命令行参数与之前版本不兼容。因此,专栏中的代码示例和命令已经过时。
我曾考虑过根据最新的 GmSSL,修改专栏文章。但看了源码之后,发现 GmSSL 到了 V3 版本之后,代码基本上推倒重来,不仅不兼容 OpenSSL,和 V2 版本也差别甚大。如果按照 GmSSL 最新版本修订文章,工作量很大。
我当时研究国密算法时,GmSSL 的版本是 2.5.4,所有在克隆 GmSSL 源码之后,切换到 V2 分支,专栏中引用到的命令、代码仍然有效。方法如下:
- 代码下载
通过git命令克隆代码库:
$ git clone https://github.com/guanzhi/GmSSL gmssl
- 编译代码
为了避免和系统的openssl库冲突,请务必指定 prefix 参数,最好指定一个有可写权限的路径:
$ cd gmssl
$ ./config --prefix=/work/gm/usr/local/gmssl
$ make
$ make install
经过上面的步骤,可执行文件会安装到 ${prefix} 的bin子目录下,而库文件则会复制到lib子目录下。
- 运行gmssl程序
因为第2步将可执行文件和库安装到了 ${prefix} 目录下,所以运行之前请指定路径:
export PATH=/work/gm/usr/local/gmssl/bin:$PATH
export LD_LIBRARY_PATH=/work/gm/usr/local/gmssl/lib:$LD_LIBRARY_PATH
然后再运行命令行工具:
$ gmssl version
GmSSL 2.5.4 - OpenSSL 1.1.0d 3 Sep 2019
表明安装成功,注意 gmssl 有个 openssl 软链接,所以使用 openssl 命令也是可以的。gmssl V2是在 openssl 源码的基础上修改,命令行工具也保持兼容,所以网上查找到的 openssl 指令和参数,在 gmssl 下同样适用。