最近在分析一个软件时需要用到加密算法,然后在网上搜索了一下,对比了网上的几个开源的加密库,最后选定OpenSSL。OpenSSL是用C写的,但包含有很多面向对象的特征,而且代码效率很高。个人觉得比起CryptPP库来容易理解,也易于使用。CryptPP是用C++写的,类的继承关系太复杂,类库代码调试、分析较难。而且OpenSSL还可以根据要求定制编译,比如某些不需要的加密算法可以屏蔽掉,这样裁减出来的库尺寸会小一些。下面说说我的OpenSSL的编译。
OpenSSL在Windows下的编译,如果使用默认配置其实不难。大致分三步,下载openssl源代码和安装Perl就不说了。
1)perl Configure VC-WIN32
2)ms\do_masm
3)执行nmake -f ms\nt.mak生成静态库,或者执行nmake -f ms\ntdll.mak生成动态库,在nmake之前最好先到VC安装目录下运行一下vcvar32.bat重新设置一下编译的路径和环境变量。
但是如果是定制编译就比较难了,摸索了很长时间,经常出现编译错误。直到无意中看了一下openssl目录下的INSTALL.W32,很多答案才找到。
这是一个教训啊,看来,什么东西拿到手上都应该仔细看看,而不应该拿到就想马上上手,这样反而可能还要多走一些弯路。很多时候盲目的在网上搜索问题的解决办法,还不如老老实实研究自带的帮助和说明,苦苦寻找的答案可能就在其中。其实开始我也不是没有看INSTALL.W32这个文档,只是不太仔细,只看了前面的编译方法,没看后面的Troubleshooting。个人认为要定制编译OpenSSL,Troubleshooting一节很重要,就用google翻译了一下,放在这里以免遗忘。
疑难排解
由于Win32下的编译只是偶尔进行测试,可能并不总是编译干净。当您运行MS \ do_ms,如果得到一个有关函数没有指定序号错误,
那么这意味着在Win32原始文件过期。你可以:
> perl util\mkdef.pl crypto ssl update
然后,ms\do_xxx不应再警告了。然而这种方法得到的序号可能不能匹配CVS树指定的序号,所以任何对这个版本的库的链接可能需要重新编译。
如果你的错误是有关不能解析符号变量的(unresolved symbols),有几种可能的原因。
如果你已禁用某些加密算法,该DLL被链接时发生这种情况,则有可能是DEF文件生成时没有清除所有关闭的符号。最简单的办法是编辑DEF文件手动将其删除。DEF文件是 ms\libeay32.def和ms\ ssleay32.def。
另一个原因是,你略过了上面提到的missing numbers错误。
如果出现警告,编译将会停止。
出现任何警告,Win32默认的Makefile将会停止。由于VC + + 对待警告有自己的做法,并不一定与其他环境发生这种情况时相符。最好的解决方法是编辑有警告的文件并修复它。或者,也可以通过编辑Makefile中CFLAG行,删除/WX选项,来关闭警告。
您可能会得到编译错误。同样你要修复这些或报告他们。
编译连接OpenSSL库的应用程序,如果你不使用多线程DLL运行时库(/md选项)您的程序几乎肯定会崩溃,因为malloc陷入混乱-在
OpenSSL DLL静态链接到一个版本,应用程序必须使用同一个版本。加CRYPTO_malloc_init()到程序调用OpenSSL库之前,可能能够解决这些问题 :这会告诉OpenSSL库使用与应用程序相同的malloc(),free()和realloc()。但是OpenSSL调用的很多标准库函数内部用到malloc()
(例如fopen()函数),OpenSSL不能改变这些,所以一般不能依靠CRYPTO_malloc_init()解决您的问题,您应该 坚持用多线程库。
连接应用程序
如果您链接静态OpenSSL库[built with ms/nt.mak],那么你需要额外链接WSOCK32.LIB,ADVAPI32.LIB,GDI32.LIB和USER32.LIB。这些开发非交互式服务应用程序可能会关注后两个库的连接,因为他们仅与交互桌面相关,对服务进程不可用。该工具包的设计检测它的目前执行的,GUI,控制台应用程序或服务,并采取相应的行动,即是否实际上使 图形用户界面调用。
如果您链接使用OpenSSL.DLLs,那么希望你将连接OpenSSL BIO layer和编译器运行时库的小“垫片”片段包含到您的应用程序代码。更多详情查一查OPENSSL_Applink引用页。
对OpenSSL的Win32编译环境可以进行多种调整。默认情况下是不编译调试符号的。编译调试符号需要在do_*批处理文件中添加'debug' 到 mk1mf.pl行。注意mk1mf.pl需要platform是命令行的最后一个参数,所以'debug'必须出现在此之前。
0.9.8 OpenSSL默认编译ENGINES到libeay32.dll库。如果在命令行对Configure 指定了“no-static-engine”选项,共享库构建时(ms\ntdll.mak)将编译
engines作为单独的DLL。
默认Win32环境是略去任何Windows NT特征。如果你想OpenSSL允许NT特征(目前只logging BIO)按照上述操作,但调用批处理文件时用do_nt.bat 代替do_ms.bat。