2.2.11 在Windows下编译OpenSSL 1.1.1
OpenSSL是一个开源的第三方库,它实现了SSL(Secure Socket Layer,安全套接层)和TLS(Transport Layer Security,安全传输层)协议,被企业应用广泛采用。对于一般的开发人员而言,在Win32 OpenSSL上下载已经编译好的OpenSSL库是省力省事的好办法。对于高级的开发用户,可能需要适当地修改或者裁剪OpenSSL,那么编译它就成为一个关键问题。考虑到我们早晚要成为高级开发用户,所以掌握OpenSSL的编译是早晚的事。下面主要讲述如何在Windows上编译OpenSSL库。
前面讲了不少理论知识,虽然枯燥,但可以从宏观层面上对OpenSSL进行高屋建瓴地了解,这样以后走迷宫时不至于迷路。下面即将进入实战环节。废话不多说,打开官网下载源码。OpenSSL的官网地址是https://www.openssl.org。这里使用的是新版本OpenSSL 1.1.1,在学习的时候我们要勇于尝试新版本。另外要注意的是,OpenSSL官方现在已停止对0.9.8和1.0.0两个版本的升级维护,还在维护老代码的同志要注意了,升级是早晚的事情。这里会下载两个版本进行演示,为了照顾喜欢尝鲜的读者,先下载目前新的版本1.1.1,下载下来的压缩文件是openssl-1.1.1.tar.gz。后面会下载一个推荐用于实际开发的版本,即1.0.2m,下载下来的压缩文件是openssl-1.0.2m.tar.gz,不求最新,但求稳定,这是一线开发的原则。另外,本书也涉及一些CentOS 7下OpenSSL的使用,使用的版本是CentOS 7自带的,也是为了稳定。
1.安装ActivePerl解释器
因为编译OpenSSL源码的过程中会用到Perl解释器,所以在编译OpenSSL库之前,还需要下载一个Perl脚本解释器,这里选用大名鼎鼎的ActivePerl,我们可以从其官方网站(https://www.activestate.com/)下载。这里下载后的文件为ActivePerl-5.26.1.2601-MSWin32-x64-404865.exe。
下载完毕后,就可以开始安装了。直接双击即可开始安装,安装时间有点长,要有点耐心,最终会提示安装成功。安装完成的界面如图2-2所示。
图2-2
2.下载OpenSSL 1.1.1
目前,OpenSSL 1.1.1b是新的版本,我们可以去官方网站下载,下载地址为https://www.openssl.org/source/。下载下来的文件名是openssl-1.1.1b.tar.gz。
下面开始我们的编译之旅。为什么要编译?因为编译后会生成库,这个库可以放到工程环境中使用。
3.安装VC
在Windows平台上,用微软Visual Studio中的C编译器生成OpenSSL的静态库或动态库。我们要在VC命令行下编译,所以需要先安装VC,至少要VC 2008,本书采用的是VC 2017,建议大家使用这个版本,以后看书的过程中有问题方便联合作者一起排查。
4.编译出32位的Debug版本的静态库
安装完ActivePerl后,就可以正式编译安装OpenSSL了。我们下载下来的openssl-1.1.1.tar.gz是一个源码压缩包,需要对其进行解压,然后编译出开发所需要的静态库或动态库。
具体安装步骤如下:
(1)解压源码目录。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017的开发人员命令提示符”,即可出现如图2-3所示的窗口。
图2-3
然后在图2-3所示的命令行窗口中输入cd d:\openssl-1.1.1b,然后输入命令:
perl Configure debug-VC-WIN32 no-shared no-asm --prefix="d:/openssl-1.1.1b/win32-debug" --openssldir="d:/openssl-1.1.1b/win32-debug/ssl"
其中,debug-VC-WIN32表示32位调试模式,no-asm表示不用汇编。
接着按回车键,然后开始自动配置,如图2-4所示。
图2-4
其中,VC-WIN32表示我们要编译出32位的版本,若要编译出Debug版本,则使用debug-VC-WIN32,若要使用Release版本的OpenSSL库,则不要加debug-。no-shared表示我们要编译出静态库,若要编译出动态库,则不要加no,用-shared即可,这个很好理解,静态库是不共享的,动态库是用来共享的。参数--prefix是OpenSSL编译完后所生成的命令程序、库、头文件等的存放路径。--openssldir是OpenSSL编译完后生成的配置文件的存放路径。
(3)编译OpenSSL。配置完成后,我们可以继续用nmake命令开始编译,在命令行窗口中输入nmake后按回车键即可开始编译,nmake程序是VC自带的命令行编译工具。这一步时间稍长,大家可以喝杯茶。编译成功后如图2-5所示。
图2-5
(4)测试编译。这一步不是必需的,但最好检查一下上一步的编译是否正确。在命令行窗口中输入命令:
nmake test
这一步时间也稍长,其实可以不用做,但笔者做了,测试全部成功,如图2-6所示。
图2-6
(5)安装。继续输入命令nmake install,执行成功后如图2-7所示。
图2-7
(6)清理。主要是删除一些中间文件。继续输入命令nmake clean。
此时,进入D:\openssl-1.1.1b\win32-debug,可以看到一些子文件夹,如图2-8所示。
图2-8
其中,bin目录下存放OpenSSL的命令行程序,利用该程序我们可以在命令行下执行一些加解密任务、证书操作任务。在lib目录下存放的就是我们编译出来的32位的静态库libcrypto.lib和libssl.lib,一般的加解密程序使用libcrypto.lib即可。include目录就是我们开发所需要的OpenSSL头文件。
现在,趁热打铁,马上来开发一个使用OpenSSL静态库的程序,以此检验我们生成的静态库是否正确。
【例2.1】使用32位OpenSSL 1.1.1的Debug静态库
(1)打开VC 2017,新建一个控制面板程序test。
(2)在test.cpp中输入代码如下:
(3)包含include目录。打开“test属性页”对话框,在界面左边选择“C/C++”→“常规”,在右边的“附加包含目录”旁输入OpenSSL头文件所在的路径D:\openssl-1.1.1b\win32-debug\include,如图2-9所示。
图2-9
然后单击“确定”按钮。这样我们的程序中包含openssl/evp.h的时候就不会出错了,因为include目录下有OpenSSL子目录。
顺便说一句,其实把include文件夹复制到自己的工程目录下也可以,但考虑到很多程序都要用到头文件,所以没必要每个工程都去复制一份include文件夹,建议放在一个公共路径下(比如D:\openssl-1.1.1b\win64-debug\include),各个开发者自己包含这个公共路径即可。
(4)添加静态库。在“test属性页”对话框中,在界面左边选择“链接器”→“常规”,在右边的“附加库目录”旁输入OpenSSL静态库所在的路径D:\openssl-1.1.1b\win32-debug\lib,如图2-10所示。
图2-10
然后单击“应用”按钮。接着展开界面左边的“链接器”→“输入”,在右边第一行“附加依赖项”右边的开头输入ws2_32.lib;Crypt32.lib;libcrypto.lib;,其中ws2_32.lib和Crypt32.lib是VC自带的库,分别实现网络功能和微软提供的加解密功能,加入这两个库的原因是libcrypto.lib依赖于它们。最后单击“确定”按钮。
(5)保存工程并运行,运行结果如图2-11所示。
图2-11
至此,说明32位的Debug版本的OpenSSL 1.1.1b静态库使用起来了。
5.编译出32位的Release版本的静态库
(1)解压源码目录(若已经存在源码目录openssl-1.1.1b,则可以不必再解压)。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017的开发人员命令提示符”,输入命令cd d:\openssl-1.1.1b,然后输入Perl命令如下:
perl Configure VC-WIN32 no-shared no-asm --prefix="d:/openssl-1.1.1b/win32-release" --openssldir="d:/openssl-1.1.1b/win32-release/ssl"
其实就是把no-shard改为shared,后面的步骤都一样,分别是:
nmake nmake test nmake install nmake clean
完毕后,我们到D:\openssl-1.1.1b\win32-release下去看,可以看到生成的各个子目录。
【例2.2】测试32位Release版本的库
(1)把例子2.1的工程复制一份,然后使用VC 2017打开工程。
(2)在工具栏选择解决方案配置为Release,如图2-12所示。
图2-12
(3)打开“test属性页”对话框,确保界面左上角的“配置”是Release,意思是我们要生成的程序是Release版本的程序,即程序中不带调试信息了。然后在界面左边选择“C/C++”→“常规”,在右边添加附加包含目录为D:\openssl-1.1.1b\win32-release\include。
(4)添加静态库。在“test属性页”对话框中,在界面左边选择“链接器”→“常规”,在右边的“附加库目录”旁输入OpenSSL静态库所在路径D:\openssl-1.1.1b\win32-release\lib,然后单击“应用”按钮。接着展开左边的“链接器”→“输入”,在右边第一行“附加依赖项”右边的开头输入ws2_32.lib;Crypt32.lib;libcrypto.lib;,其中ws2_32.lib和Crypt32.lib是VC自带的库,分别实现网络功能和微软提供的加解密功能,加入这两个库的原因是libcrypto.lib依赖于它们。最后单击“确定”按钮。
(5)保存工程并运行,运行结果如图2-13所示。
图2-13
至此,说明32位的Release版本的静态库使用起来了。
6.编译出32位的Debug版本的动态库
(1)解压源码目录(如果前面解压过了,就不必再解压)。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017的开发人员命令提示符”,输入命令cd d:\openssl-1.1.1b,然后输入Perl命令如下:
perl Configure debug-VC-WIN32 shared no-asm --prefix="d:/openssl-1.1.1b/win32-shared-debug" --openssldir="d:/openssl-1.1.1b/win32-shared-debug/ssl"
后面的步骤都一样,分别是:
nmake nmake test nmake install nmake clean
完毕后,我们到D:\openssl-1.1.1b\win32-shared-debug下查看,可以看到生成的各个子目录。
【例2.3】使用32位的Debug版本的动态库
(1)打开VC 2017,新建一个控制面板程序test。
(2)在test.cpp中输入代码如下:
(3)包含include目录。打开“test属性页”对话框,在界面左边选择“C/C++”→“常规”,在右边的“附加包含目录”旁输入OpenSSL头文件所在的路径D:\openssl-1.1.1b\win32-shared-debug\include。
(4)添加链接符号库。在“test属性页”对话框中,在界面左边选择“链接器”→“常规”,在右边的“附加库目录”旁输入OpenSSL引用库(注意虽然名字和静态库一样,但动态库中叫引用库,用于编译时的符号引用)所在的路径D:\openssl-1.1.1b\win32-shared-debug\lib,然后单击“应用”按钮。接着展开界面左边的“链接器”→“输入”,在右边第一行“附加依赖项”右边的开头输入ws2_32.lib;Crypt32.lib;libcrypto.lib;,其中ws2_32.lib和Crypt32.lib是VC自带的库,分别实现网络功能和微软提供的加解密功能,加入这两个库的原因是libcrypto.lib依赖于它们。最后单击“确定”按钮。
(5)把D:\openssl-1.1.1b\win32-shared-debug\bin下的libcrypto-1_1.dll复制到我们的解决方案的debug目录下,即和test.exe同一个目录下。
(6)保存工程并运行,运行结果如图2-14所示。
图2-14
7.编译出32位的Release版本的动态库
(1)解压源码目录。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017开发人员命令提示符”,输入命令cd d:\openssl-1.1.1b,然后输入Perl命令如下:
perl Configure VC-WIN32 shared no-asm --prefix="d:/openssl-1.1.1b/win32-shared-release" --openssldir="d:/openssl-1.1.1b/win32-shared-release/ssl"
其实就是把no-shard改为shared,后面的步骤都一样,分别是:
nmake nmake test nmake install nmake clean
完毕后,我们到D:\openssl-1.1.1b\win32-shared-release下去看,可以看到生成的各个子目录。
【例2.4】使用32位的release版本的动态库
(1)打开VC 2017,新建一个控制面板程序test。
(2)在test.cpp中输入代码如下:
(3)将界面左上角工具栏上的选择解决方案配置为Release,意思是我们要生成的程序是Release版本的程序,即程序中不带调试信息了。在界面左边选择“C/C++”→“常规”,在右边的“附加包含目录”旁输入OpenSSL头文件所在的路径D:\openssl-1.1.1b\win32-shared-release\include。
(4)添加链接符号库。在“test属性页”对话框中,在界面左边选择“链接器”→“常规”,在右边的“附加库目录”旁输入OpenSSL引用库所在的路径D:\openssl-1.1.1b\win32-shared-release\lib,然后单击“应用”按钮。接着展开左边的“链接器”→“输入”,在右边第一行“附加依赖项”右边的开头输入ws2_32.lib;Crypt32.lib;libcrypto.lib;,其中ws2_32.lib和Crypt32.lib是VC自带的库,分别实现网络功能和微软提供的加解密功能,加入这两个库的原因是libcrypto.lib依赖于它们。最后单击“确定”按钮。
(5)把D:\openssl-1.1.1b\win32-shared-release\bin下的libcrypto-1_1.dll复制到解决方案的release目录下,即和test.exe同一个目录下。
(6)在工具栏切换解决方案配置为Release,保存工程并运行,运行结果如图2-15所示。
图2-15
8.编译出64位的Debug版本的静态库
(1)解压源码目录。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017的开发人员命令提示符”,输入命令cd d:\openssl-1.1.1b,然后输入Perl命令如下:
perl Configure debug-VC-WIN64A no-shared no-asm --prefix="d:/openssl-1.1.1b/win64-debug" --openssldir="d:/openssl-1.1.1b/win64-debug/ssl"
debug-VC-WIN64A表示64位调试模式。
后面的步骤都一样,分别是:
nmake nmake test nmake install nmake clean
完毕后,我们到D:\openssl-1.1.1b\win64-debug下去看,可以看到生成的各个子目录,如果我们进入lib子目录下去看,可以发现libcrypto.lib的文件尺寸比32位的版本大了2MB多,如图2-16所示。
图2-16
【例2.5】验证64位Debug版本的OpenSSL静态库
(1)打开VC 2017,新建一个控制面板程序test。
(2)在test.cpp中输入代码如下:
(3)在工具栏上的解决方案平台选择“x64”,意思是我们要生成的程序是64位的程序,如图2-17所示。
图2-17
打开“test属性页”对话框,在左边选择“C/C++”→“常规”,在右边的“附加包含目录”旁输入OpenSSL头文件所在的路径D:\openssl-1.1.1b\win64-debug\include。
(4)添加链接符号库。在“test属性页”对话框中,在左边选择“链接器”→“常规”,在右边的“附加库目录”旁输入OpenSSL静态库所在的路径D:\openssl-1.1.1b\win64-debug\lib,然后单击“应用”按钮。接着展开左边的“链接器”→“输入”,在右边第一行“附加依赖项”右边的开头输入ws2_32.lib;Crypt32.lib;libcrypto.lib;,其中ws2_32.lib和Crypt32.lib是VC自带的库,分别实现网络功能和微软提供的加解密功能,加入这两个库的原因是libcrypto.lib依赖于它们。最后单击“确定”按钮。
(5)保存工程并运行,运行结果如图2-18所示。
图2-18
9.编译出64位的Release版本的静态库
(1)解压源码目录。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017的开发人员命令提示符”,输入命令cd d:\openssl-1.1.1b,然后输入Perl命令如下:
perl Configure VC-WIN64A no-shared no-asm --prefix="d:/openssl-1.1.1b/win64-release" --openssldir="d:/openssl-1.1.1b/win64-release/ssl"
后面的步骤都一样,分别是:
nmake nmake test nmake install nmake clean
完毕后,我们到D:\openssl-1.1.1b\win64-release下去看,可以看到生成的各个子目录。
【例2.6】验证64位Release版本的OpenSSL静态库
(1)打开VC 2017,新建一个控制面板程序test。
(2)在test.cpp中输入代码如下:
#pragma comment表示以代码方式引用库。这样就不用在工程属性中设置了。
(3)打开“test属性页”对话框,新建一个x64平台,在工程属性中切换到Release模式,然后添加头文件包含路径:D:\openssl-1.1.1b\win64-release\include,以及静态库路径:D:\openssl-1.1.1b\win64-release\lib。这里讲的简略了,路径具体在哪个位置添加,前面已经介绍过了。
(4)保存工程,然后在工具栏上选择解决方案平台为x64,解决方案配置为Release,然后运行工程,运行结果如图2-19所示。
图2-19
10.编译出64位的Debug版本的动态库
(1)解压源码目录。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017的开发人员命令提示符”(注意是x64本机工具命令提示,不要选择其他的),输入命令cd d:\openssl-1.1.1b,然后输入Perl命令如下:
perl Configure debug-VC-WIN64A shared no-asm --prefix="d:/openssl-1.1.1b/win64-shared-debug" --openssldir="d:/openssl-1.1.1b/win64-shared-debug/ssl"
后面的步骤都一样,分别是:
nmake nmake test nmake install nmake clean
完毕后,我们到D:\openssl-1.1.1b\win64-shared-debug下去看,可以看到生成的各个子目录。
【例2.7】验证64位Debug版本的OpenSSL动态库
(1)打开VC 2017,新建一个控制面板程序test。
(2)在test.cpp中输入代码如下:
#pragma comment表示以代码方式引用符号库。这样就不用在工程属性中设置了。
(3)打开“test属性页”对话框,新建一个x64平台,然后添加头文件包含路径:D:\openssl-1.1.1b\win64-shared-debug\include,以及符号库路径:D:\openssl-1.1.1b\win64-shared-debug\lib。这里讲的简略了,路径具体在哪个位置添加,前面已经介绍过了。
把D:\openssl-1.1.1b\win64-shared-debug\bin下的libcrypto-1_1-x64.dll复制到解决方案路径下的x64文件夹下的Debug子目录下。
(4)保存工程,然后在工具栏上选择解决方案平台为x64,然后运行工程,运行结果如图2-20所示。
图2-20
11.编译出64位的Release版本的动态库
(1)解压源码目录。把openssl-1.1.1b.tar.gz复制到某个目录下,比如D:,然后解压缩,解压后的目录为D:\openssl-1.1.1b,进入D:\openssl-1.1.1b,就可以看到各个子文件夹了。
(2)配置OpenSSL。打开VC 2017的开发者命令行提示窗口,单击“开始”→“Visual Studio 2017”→“Visual Studio Tools”→“VS 2017的开发人员命令提示符”(注意是x64本机工具命令提示,不要选择其他的),输入命令cd d:\openssl-1.1.1b,然后输入Perl命令如下:
perl Configure VC-WIN64A shared no-asm --prefix="d:/openssl-1.1.1b/win64-shared-release" --openssldir="d:/openssl-1.1.1b/win64-shared-release/ssl"
后面的步骤都一样,分别是:
nmake nmake test nmake install nmake clean
完毕后,我们到D:\openssl-1.1.1b\win64-shared-release下去看,可以看到生成的各个子目录。
【例2.8】验证64位Release版本的OpenSSL动态库
(1)打开VC 2017,新建一个控制面板程序test。
(2)在test.cpp中输入代码如下:
#pragma comment表示以代码方式引用符号库。这样就不用在工程属性中设置了。
(3)打开“test属性页”对话框,新建一个x64平台,在工程属性中切换到Release模式,然后添加头文件包含路径:D:\openssl-1.1.1b\win64-shared-release\include,以及静态库路径:D:\openssl-1.1.1b\win64-shared-release\lib。这里讲的简略了,路径具体在哪个位置添加,前面已经介绍过了。
(4)保存工程,然后在工具栏上选择解决方案平台为x64,解决方案配置为Release,并把D:\openssl-1.1.1b\win64-shared-release\bin下的libcrypto-1_1-x64.dll复制到解决方案的x64文件夹下的Release文件夹下,然后运行工程,运行结果如图2-21所示。
图2-21
以上我们对新版本的OpenSSL的各种库都进行了编译和测试,虽然略显烦琐,但也是必要的,尤其是在实际项目中使用之前,建议大家都测试一下,库好才用。