购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4 国产密码开发库GmSSL

长城永不倒,国货当自强。随着我国科技的发展,现在我们自己也拥有了包含多种国内标准算法的密码开发库,那就是功能强大的GmSSL。作为后起之秀,GmSSL丝毫不逊于国际密码算法库,而且更加适用于开发国产密码应用系统,因为它对于国密算法的支持更完善。如果以后要在国内开发密码应用系统,建议学习GmSSL。

GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法、SM2国密数字证书及基于SM2证书的SSL/TLS安全通信协议,支持国密硬件密码设备,提供符合国密规范的编程接口与命令行工具,可以用于构建PKI/CA、安全通信、数据加密等符合国密标准的安全应用。GmSSL项目是OpenSSL项目的分支,并与OpenSSL保持接口兼容。因此,GmSSL可以替代应用中的OpenSSL组件,并使应用自动具备基于国密的安全能力。GmSSL项目采用对商业应用友好的类BSD开源许可证,开源且可以用于闭源的商业应用。

GmSSL项目由北京大学关志副研究员的密码学研究组开发维护,项目源码托管于GitHub。自2014年发布以来,GmSSL已经在多个项目和产品中获得部署与应用,并获得2015年度“一铭杯”中国Linux软件大赛二等奖(年度最高奖项)与开源中国密码类推荐项目。GmSSL项目的核心目标是通过开源的密码技术推动国内网络空间的安全建设。

2.4.1 GmSSL的特点

GmSSL作为我国自主研发的密码算法库,在功能和性能上有着自己的特点:

(1)支持SM2/SM3/SM4/SM9/ZUC等已公开的国密算法。

(2)支持国密SM2双证书SSL套件和国密SM9标识密码套件。

(3)高效实现,在主流处理器上可完成4.5万次SM2签名。

(4)支持动态接入具备SKF/SDF接口的硬件密码模块(SKF是USBKEY/TF卡的应用接口规范,SDF是密码设备的应用接口规范)。

(5)支持门限签名、秘密共享和白盒密码等高级安全特性。

(6)支持Java、Go、PHP等多语言接口绑定和REST服务接口。

2.4.2 GmSSL的一些历史

2018年12月18日,GmSSL已部署Travis和AppVeyor持续集成工具,用以测试Linux和Windows环境下的编译和安装。

2018年10月13日,GmSSL-2.4.0发布,支持国密256位Barreto-Naehrig曲线参数(sm9bn256v1)上的SM9算法。

2018年6月27日,密码行业标准化技术委员会公布了所有密码行业的标准文本。

2018年5月27日,GmSSL增加SM4算法的Bitslice实现。

2018年3月21日,IESG工作组批准TLS1.3协议作为建议标准。

2018年3月13日,增加GmSSL PHP语言API。

2017年11月11日,中国可信云计算社区暨中国开源云联盟安全论坛在北京大学举办。

2017年5月15日,发布GmSSL-1.3.0二进制包下载(5.4MB)。

2017年4月30日,增加GmSSL Go语言API。

2017年3月2日,GmSSL项目注册了OID {iso(1) identified-organization(3) dod(6) internet(1)private(4) enterprise(1) GmSSL(49549)}。

2017年2月12日,支持完整的密码库Java语言封装GmSSL-Java-Wrapper。

2017年1月18日,更新了项目主页。

2.4.3 什么是国密算法

GmSSL最大的特点是对国密算法的强大支持,可以说,它就是为国密算法而生的。那什么是国密算法呢?国密算法是国家商用密码算法的简称。自2012年以来,国家密码管理局以《中华人民共和国密码行业标准》的方式陆续公布了SM2/SM3/SM4等密码算法标准及其应用规范。其中,SM代表“商密”,即商用的、不涉及国家秘密的密码技术。SM2为基于椭圆曲线密码的公钥密码算法标准,包含数字签名、密钥交换和公钥加密,用于替换RSA/Diffie-Hellman/ECDSA/ECDH等国际算法;SM3为密码哈希算法,用于替代MD5/SHA-1/SHA-256等国际算法;SM4为分组密码算法,用于替代DES/AES等国际算法;SM9为基于身份的密码算法,可以替代基于数字证书的PKI/CA体系。通过部署国密算法,可以降低由弱密码和错误实现带来的安全风险和部署PKI/CA带来的开销。

由于密码在国民经济中的敏感性,因此涉密的系统采用国密算法是大势所趋。学习和使用国密算法也是每个密码行业开发者的基本功。

2.4.4 GmSSL的下载

我们可以到GitHub网站上下载源码,网址是https://github.com/guanzhi/GmSSL。打开网页后,单击右方的Code下拉按钮,然后在下拉框中单击Download ZIP按钮,就可以下载了,如图2-48所示。

图2-48

下载下来后是一个ZIP文件,文件名是GmSSL-master.zip。当前下载的新版本是2.5.4。

2.4.5 在Windows下编译安装GmSSL

我们把下载下来的GmSSL-master.zip放到D盘(也可以放到其他盘)并解压。

在Windows下编译GmSSL需要先安装ActivePerl和Visual Studio 2017,相信读者编译OpenSSL的时候已经安装过这两个工具了,这里不再赘述。然后以管理员身份打开Visual Studio Tools下的“VS 2017的开发人员命令提示符”,并定位到D:\GmSSL-master,接着运行:perl Configure VC-WIN32,运行后如图2-49所示。

然后输入编译命令:nmake,稍等片刻,编译完毕,如图2-50所示。

图2-49

图2-50

接着输入安装命令:nmake install,再次稍等片刻,安装完毕,如图2-51所示。

安装成功,可在C:\Program Files (x86)\GmSSL下找到bin、html、include、lib等文件夹,如图2-52所示。

图2-51

图2-52

其中,目录bin存放GmSSL命令行工具程序,目录html存放一些帮助文件,目录include存放开发所需要的头文件,目录lib存放开发所需的库文件,这些都和OpenSSL类似。

下面是一些常见的编译错误及原因。

(1)安装的Visual C++版本较低,比如使用Visual C++ 6、Visual Studio 2008。

(2)源码不干净或并非最新,建议从一份干净的(没有已经编译出来的对象文件或汇编文件)最新的Master分支源代码开始编译。

(3)编译系统没有找到nmake。实际上nmake是Visual Studio自带的工具,不需要单独安装。编译系统无法找到nmake的原因是没有在Visual Studio的命令行环境下执行编译指令。

(4)无法执行nmake install。这个命令需要以管理员身份执行。

(5)对象文件(.obj)和目标平台不一致,通常是由于在Visual Studio的32位控制台下执行Perl Configure VC-WIN64A,或者在Visual Studio的64位控制台下执行Perl Configure VC-WIN32导致的。

1.验证命令行工具

为了方便在命令行下使用gmssl命令,可以把命令程序所在的路径加入系统的Path变量中,在桌面上对“计算机”右击,选择“属性”→“高级系统设置”→“高级”→“环境变量”,选中系统变量下的Path,然后单击“编辑”按钮,并在其末尾加入路径“C:\Program Files(x86)\GmSSL\bin”,注意前面要用分号隔开,如图2-53所示。

图2-53

单击“确定”按钮关闭对话框。然后重新打开一个新的命令行窗口,并输入命令gmssl,可以发现出现提示符>了,此时可以输入gmssl的子命令,比如help,如图2-54所示。

也可以输入version查看版本号,如图2-55所示。

图2-54

图2-55

如果要退出GmSSL命令行,可以输入quit。

下面我们用SM3命令来计算一个Hash值。首先在D盘下新建一个文本文件,文件名是my.txt,并输入3个字符abc,然后保存。接着在命令行下输入命令:sm3 D:\my.txt,运算结果如下:

GmSSL> sm3 d:\my.txt
SM3(d:\my.txt)= 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0

其实,GmSSL的命令行操作和OpenSSL大同小异。至此,命令行验证正确。下面开始程序验证。

2.程序验证GmSSL

GmSSL提供了EVP (Envelop的简称)系列API供开发者使用。EVP API是GmSSL的密码服务接口,它屏蔽了具体算法的细节,为上层应用提供统一、抽象的接口。该接口的头文件为openssl/evp.h,所对应的函数库为libcrypto。

【例2.13】用代码验证GmSSL

(1)打开VC 2017,新建一个控制面板工程,工程名是test。

(2)在test.cpp中输入代码如下:

代码很简单,我们只是加载了所有密码函数并释放空间,并没有做实际的运算,但用来测试GmSSL库已经够用了。

然后,打开工程属性,在左边选中“C/C++”,然后在右边的“附加包含目录”旁输入“D:\gmssl-master\include”。接着,在右边选中“连接器”→“常规”,在右边的“附加库目录”旁输入“D:\gmssl-master”,在右边选中“输入”,在左边的“附加依赖性”旁边输入“libcrypto.lib;”,最后单击“确定”按钮。这样头文件路径、库路径和库名称都设置好了。

D:\gmssl-master下的libcrypto.lib是我们编译生成的静态库。

(3)保存工程并按Ctrl+F5键运行,运行结果如图2-56所示。

图2-56

2.4.6 在Linux下编译安装GmSSL

这里使用的是CentOS 7(也可以使用其他版本的Linux)。以root账户登录Linux,把下载下来的GmSSL压缩包GmSSL-master.zip放到Linux下,然后解压:

unzip GmSSL-master.zip

接着进入文件夹GmSSL-master,开始配置:

[root@localhost soft]# cd GmSSL-master/
[root@localhost GmSSL-master]# ./config --prefix=/usr/local/mygmssl

其中,--prefix用来指定安装目录。也可以不用--prefix,那么将采用默认路径,即命令程序会安装在/usr/local/bin下,头文件会安装到/usr/local/include下,库文件会存放到/usr/local/lib下。这里为了安装后简洁,我们采用--prefix,这样安装后的可执行程序、头文件和库文件分别会放到mygmssl目录下的bin、include和lib中。目录mygmssl会自动建立,不需要预先手工建好。

配置完毕后,开始漫长的编译:

[root@localhost GmSSL-master]# make

这个过程有点长,读者可以去泡壶茶。编译完毕,开始安装:

[root@localhost GmSSL-master]# make install

这个过程也稍长,可以喝会茶。安装完毕后,我们可以进入/usr/local/mygmssl,使用ls查看可以发现所有东西都在:

[root@localhost local]# cd mygmssl/
[root@localhost mygmssl]# ls
bin include lib share ssl
[root@localhost mygmssl]#

其中,bin存放命令工具程序,include存放头文件,lib存放库文件,这都是开发所需要的。而/usr/local/bin、/usr/local/include和/usr/local/lib依旧为空:

[root@localhost /]# cd /usr/local/lib
[root@localhost lib]# ls
[root@localhost lib]# cd ../include
[root@localhost include]# ls
[root@localhost include]# cd ../bin
[root@localhost bin]# ls
[root@localhost bin]#

如果我们不指定安装目录,采用默认安装目录,这3个文件夹下都会有东西,多疑的读者可以尝试一下。

1.验证命令行工具

安装完毕后,验证是否能正常工作。前面我们通过指定安装目录的方式来安装,其实这样也有不便的地方,就是运行命令程序gmssl的时候,要到/usr/local/mygmssl/bin下执行。如果默认安装,存放到/usr/locl/bin下,那么可以在任意目录运行gmssl。怎么办呢?可以做一个链接:

[root@localhost bin]# ln -s /usr/local/mygmssl/bin/gmssl /usr/local/bin/gmssl

这样,/usr/local/bin/下有一个软链接gmssl指向/usr/local/mygmssl/bin下的程序gmssl。此时,可以在任意目录下执行gmssl,操作后却失败了:

[root@localhost ~]# gmssl
gmssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory

gmssl运行需要动态库libssl.so.1.1,但是没找到。通过搜索发现,该库位于/usr/local/mygmssl/lib/下:

[root@localhost GmSSL-master]# find / -name libssl.so.1.1
/usr/local/mygmssl/lib/libssl.so.1.1

再查看其大小:

可以看到有548字节,确实是一个文件,而不是链接。du用于查看文件大小的命令。

如何让gmssl找到libssl.so.1.1呢?我们知道,在CentOS 7下,可执行程序会自动到系统路径(比如/usr/lib64/下)去搜索所需的库。那libssl.so.1.1放到/usr/lib64下,不就可以了。其实不需要实际复制库文件过去,只需要做一个软链接,即在/usr/lib64/下新建一个软链接,使其指向/usr/local/mygmssl/lib/libssl.so.1.1即可,这样可以节省磁盘空间。在命令行下输入:

[root@localhost GmSSL-master]# ln -s /usr/local/mygmssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1

再次运行gmssl:

     [root@localhost GmSSL-master]# gmssl
     gmssl: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or
directory

可以发现错误提示变了,找不到另一个共享库libcrypto.so.1.1了,这说明libssl.so.1.1找到了。我们继续搜索libcrypto.so.1.1,凭经验应该也在/usr/local/mygmssl/lib/下。果然:

找到就好办了,继续在/usr/lib64/下建立软链接指向/usr/local/mygmssl/lib/libcrypto.so.1.1:

[root@localhost lib]# ln -s /usr/local/mygmssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1

再次运行gmssl,发现出现提示符了,说明终于成功了:

我们可以输入version和help命令来测试一下:

发现都成功了。下面准备运算abc的SM3哈希值,我们在/root下用vi新建一个文件my.txt,输入abc三个字符,然后保存。再回到GmSSL>下,再输入一个SM3运算命令:

GmSSL> sm3 /root/my.txt
SM3(/root/my.txt)= 12d4e804e1fcfdc181ed383aa07ba76cc69d8aedcbb7742d6e28ff4fb7776c34

可以发现,正确输出SM3哈希值了。细心的读者可能会发现,怎么同样是内容为abc的文本文件,结果却和Windows下的不同?这是因为,所有的linux会自动加上一个文件结束符0a(即LF),这样导致my.txt的实际内容(16进制)是6162630a,我们可以用xxd命令查看一下:

xxd命令以16进制显示文件内容。因此,这里的SM3其实是对4个字符进行SM3运算,而Windows下的SM3是对3个字符进行运算,结果自然不同了。

此外,也可以不在GmSSL提示符下测试SM3,可以在普通Linux命令行下直接测试sm3:

[root@localhost test]# echo -n "abc" | gmssl sm3
(stdin)= 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0

至此,SM3命令测试成功。下面进入代码程序测试验证阶段。

2.程序验证GmSSL

GmSSL提供了EVP(Envelop的简称)系列API供开发者使用。EVP API是GmSSL密码服务接口,它屏蔽了具体算法的细节,为上层应用提供统一、抽象的接口。该接口的头文件为openssl/evp.h。所对应的函数库为libcrypto。

【例2.14】在CentOS 7下用代码验证GmSSL

(1)在Windows下打开UE(或其他编辑器),然后输入代码如下:

(2)保存代码为test.cpp,上传到CentOS 7下,在命令行下编译并运行:

[root@localhost test]# g++ test.cpp -o test -I/usr/local/mygmssl/include -L/usr/local/mygmssl/lib -lcrypto
[root@localhost test]# ./test
Under Linux,call GmSSL lib ok

至此,在Linux下用代码验证GmSSL成功。

2.4.7 默认编译安装GmSSL

考虑到不少朋友或许更喜欢在默认路径下安装GmSSL,因此我们进行默认配置、编译和安装。这里使用的是CentOS 7(也可以使用其他版本的Linux)。以root账户登录Linux,把下载下来的GmSSL压缩包GmSSL-master.zip放到Linux下,然后解压:

unzip GmSSL-master.zip

接着进入文件夹GmSSL-master,开始配置:

配置完毕后,开始漫长的编译:

[root@localhost GmSSL-master]# make

这个过程有点长,读者可以去泡壶茶。编译完毕,开始安装:

[root@localhost GmSSL-master]# make install

这个过程也稍长,可以喝会茶。安装完毕后,我们可以进入/usr/local/include,使用ls查看可以发现多了openssl目录。在/usr/local/lib64/下也多了静态库(libcrypto.a和libssl.a)和共享库(libcrypto.soh和libssl.so),如图2-57所示。

图2-57

下面做两个软链接,让gmssl程序可以找到libcrypto.so.1.1.和libssl.so.1.1:

[root@localhost local]# ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
[root@localhost local]# ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1

ln是建立软链接的命令,用法为“ln -s源文件 目标文件”。源:实际存放文件的位置。再执行gmssl,发现可以运行了:

[root@localhost local]# gmssl
GmSSL> version
GmSSL 2.5.4 - OpenSSL 1.1.0d  3 Sep 2019
GmSSL> quit
[root@localhost local]#

下面在普通Linux命令行下直接测试SM3:

[root@localhost test]# echo -n "abc" | gmssl sm3
(stdin)= 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0

命令行验证结束,下面再用程序来验证。

【例2.15】在CentOS 7下用代码验证默认安装的GmSSL

(1)在Windows下打开UE(或其他编辑器),然后输入代码如下:

(2)保存代码为test.cpp,上传到CentOS 7下,在命令行下编译并运行:

[root@localhost test]# g++ test.cpp -o test -I/usr/local/include -L/usr/local/lib64/ -lcrypto
[root@localhost test]# ./test
Under Linux,call GmSSL lib ok

至此,在Linux下用代码验证默认安装的GmSSL成功。

2.4.8 在老版本的Linux下编译安装GmSSL

考虑到一些老项目所在的平台是老内核版本的Linux,但也想用一下GmSSL,因此我们在Linux内核2.6的一些操作系统下编译、安装和测试GmSSL。

1.编译、安装Perl

这里采用内核是2.6的老版本Linux,通常会提示少了Perl:

[root@localhost GmSSL-master]# ./config
Operating system: x86_64-whatever-linux2
Perl v5.10.0 required--this is only v5.8.8, stopped at ./Configure line 13.
Perl v5.10.0 required--this is only v5.8.8, stopped at ./Configure line 13.
This system (linux-x86_64) is not supported. See file INSTALL for details.

提示现在系统中只有版本为5.8.8的Perl,而GmSSL需要5.10.0版本。所以需要先装5.10.0版本的Perl。

我们也可以通过perl -v来查看现有版本:

[root@localhost perl-5.10.0]# perl -v
This is perl, v5.8.8 built for x86_64-linux-thread-multi
Copyright 1987-2006, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

并且系统自带的Perl程序位于/usr/bin/下,我们可以用命令ll查看:

[root@localhost perl-5.10.0]# ll /usr/bin/perl
-rwxr-xr-x 2 root root 19360 2007-10-19 01:35 /usr/bin/perl

下面开始编译安装Perl 5.10,并将老版本替换掉。首先是配置:

[root@localhost perl-5.10.0]# ./Configure -des -Dprefix=/usr/local/perl

参数-Dprefix指定安装目录为/usr/local/perl。

然后就是make和make install:

[root@localhost perl-5.10.0]#make

稍等片刻,编译完毕,开始安装:

[root@localhost perl-5.10.0]#make install

如果这个过程没有错误的话,那么恭喜你安装完成了,是不是很简单?接下来替换系统原有的Perl,有新的就使用新的。

#mv /usr/bin/perl /usr/bin/perl.bak
#ln -s /usr/local/perl/bin/perl /usr/bin/perl

此时,如果使用perl -v查看版本,对于有些老系统会提示没有这个文件,必须重启操作系统,然后就可以看到新版本提示了:

[root@localhost ~]# perl -v

This is perl, v5.10.0 built for x86_64-linux

Copyright 1987-2007, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

2.编译安装GmSSL

Perl 5.10.0安装升级成功后,就开始安装GmSSL。安装GmSSL的步骤和前面一样。最好先设置目录下所有的文件为最高权限:

chmod -R 777 GmSSL-master

其中,-R表示级联应用到目录里的所有子目录和文件,777表示所有用户都拥有最高权限(可自定权限码)。

然后进入GmSSL-master,开始三部曲:config、make和make install:

[root@localhost GmSSL-master]# ./config
[root@localhost GmSSL-master]# ./make
[root@localhost GmSSL-master]# ./make install

稍等片刻,安装完毕后,将在/usr/local/lib64/下生成库文件:

[root@localhost lib64]# ls
engines-1.1 libcrypto.a libcrypto.so libcrypto.so.1.1 libssl.a libssl.so libssl.so.1.1 pkgconfig
[root@localhost lib64]# pwd
/usr/local/lib64

并且,将在/usr/local/include/下生成头文件所在的目录openssl:

[root@localhost include]# ls
ansidecl.h bfd.h bfdlink.h dis-asm.h gdb openssl plugin-api.h symcat.h
[root@localhost include]# pwd
/usr/local/include

此时若执行gmssl程序,则会发现是执行不了的,提示少了库。下面做两个软链接,让gmssl程序可以找到libcrypto.so.1.1.和libssl.so.1.1:

[root@localhost local]# ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
[root@localhost local]# ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1

ln是建立软链接的命令,用法为“ln -s源文件 目标文件”。源:实际存放文件的位置。

再执行gmssl,发现可以运行了:

[root@localhost include]# gmssl
GmSSL> version
GmSSL 2.5.4 - OpenSSL 1.1.0d 3 Sep 2019
GmSSL>

最后用代码验证一下。

【例2.16】在CentOS 7下用代码验证默认安装的GmSSL

(1)在Windows下打开UE(或其他编辑器),然后输入代码如下:

(2)保存代码为test.cpp,上传到CentOS 7下,在命令行下编译并运行:

[root@localhost test]# g++ test.cpp -o test -I/usr/local/include -L/usr/local/lib64/ -lcrypto
[root@localhost test]# ./test
Under Linux,call GmSSL lib ok

至此,在老版本的Linux下用代码验证默认安装的GmSSL成功。 Bv4fb17wVuleo0PPIFeNk87iQdsk4W/5w4igvCOgKCgiFRfhFtQxokc19z62Nt7s

点击中间区域
呼出菜单
上一章
目录
下一章
×