OpenSSL的编译、安装以及加密解密实践

【摘要】
本文主要介绍了使用OpenSSL工具生成RSA**对,同时对文件进行RSA加密以及解密过程。
【关键词】
OpenSSL;RSA加密解密;

一、 问题背景
一些工具的加密签名方式,使用的是MD5加上固定扰码的方式,通过反编译的方法存在被**的风险,大大降低了工具的安全性。因此考虑采用业界通用的RSA加密方式进行签名,增加其安全性。
RSA是一个非对称加密算法。简单说来,非对称加密算法就是说加密解密一个文件需要有两个**,一个用来加密,为公钥,一个用来解密,为私钥。证书可以用来授权公钥的使用。这就需要使用到非对称的**对和一些加密解密的操作。而OpenSSL是一个集成了众多密码算法及实用工具。我们即可以利用它提供的命令台工具生成**、证书来加密解密文件,也可以在利用其提供的API接口在代码中对传输信息进行加密。
本文简单介绍使用OpenSSL的RSA加密,其中主要涉及利用公钥和**加解密文件,没有涉及对证书的操作。
二、 OpenSSL的编译安装

  1. 安装perl
    编译openssl,首先需要安装perl,可以到网上下载安装软件,或是服务器上下载版本,
    我使用的版本为ActivePerl-5.28.1.2801;安装完毕后,还需要配置环境变量%PATH%.重启生效,重启生效,重启生效。运行“CMD”命令,perl –version,正确显示版本信息则说明Perl安装成功,可以开始使用Perl的相关命令来进行OpenSSL的编译了。
    OpenSSL的编译、安装以及加密解密实践

环境变量配置如下:
OpenSSL的编译、安装以及加密解密实践

  1. VS2010环境下编译安装OpenSSL
    首先可以到OpenSSL的官网上下载到openssl的源代码,我使用的版本是openssl-1.1.0,下载后解压到指定目录下,接下来进行编译工作。
    (1)使用VS2010下的Visual Studio 2010 Command Prompt进入控制台模式
    开始菜单->所有程序->Microsoft->Microsoft Visual Studio 2010->Visual Studio Tools->Visual Studio 2010 Command Prompt。, 命令行键入vcvars32,运行vcvars32.bat.
    OpenSSL的编译、安装以及加密解密实践

(2) 进入openssl源码的目录
命令行键入 cd D:\Program Files\openssl-1.0.1t //把路径替换成自己的源码路径
(3) 命令行键入 perl configure VC-WIN32–prefix=d:\进行配置,如下图所示完成配置。
OpenSSL的编译、安装以及加密解密实践
备注:我们的编译环境都是32位的,因此只要选择VC-WIN32即可,如果是64位的则为VC-WIN64A
操作
1)perl Configure VC-WIN32 [no-shared] [no-asm] [no-tests] [–debug] --prefix=d:\openssllib
VC-WIN32:可根据需要修改为64位等,no-shared为编译静态库,不加此项默认编译出的是动态库;no-tests为不需要tests功能,如果只需要openssl的库可以加上此项,否则可能会出很多错误导致编译不过;–debug为编译debug版,不加此项默认编译出的是release版。
2)nmake,编译通过后再nmake install就安装到–prefix=指定的目录了。
3)如果要编译多个版本(release,debug),最好先nmake clean下,再重复第3步骤。
注意,该方法只适用于openssl 1.0,1版本及以下,也就是说openssl-1.1.0以上的版本configure的时候不会生成msdo_
.bat等等东西。原来VC自带的构建程序已经没有”ms\do”系列的程序了。直接nmake即可编译,但是编译会有异常*

(4)命令行键入 ms\do_ms
OpenSSL的编译、安装以及加密解密实践
(5)编译分两种情况,生成静态库和动态库
如果是编译OpenSSL动态库,则在命令行键入 nmake -f ms\ntdll.mak编译成功课在文件夹out32dll里面查看输出的文件,包括应用程序的exe文件、lib文件、dll文件。
如果是编译OpenSSL静态库,则在命令行键入 nmake -f ms\nt.mak编译成功课在文件夹out32里面查看输出的文件,包括应用程序的exe文件、lib文件。
至此,将OpenSSL下的include文件夹、lib文件、dll文件、exe文件考出,到时使用的时候包含进去就行了。采用静态编译主要的2个lib文件如下图所示。
OpenSSL的编译、安装以及加密解密实践
3. 编译OpenSSL可能遇到的问题

  1. 启用Windows控制台(运行cmd)进行编译,执行第5步nmake -f ms\ntdll.mak或nmake -f ms\nt.mak会报错:‘nmake’ 不是内部或外部命令,也不是可运行的程序或批处理文件。
  2. 启用SDK Command Prompt进行编译,执行第5步nmake -f ms\ntdll.mak或nmake -f ms\nt.mak会报错:ms\uplink.c(11) : fatal error C1083: Cannot open include file: ‘windows.h’: No such file or directoryNMAKE : fatal error U1077: ‘“D:\Program Files\Microsoft Visual Studio10.0\VC\bin\cl.EXE”’ : return code ‘0x2’ Stop.

上述问题解决方案:

  1. 严格按第1步操作,启动Visual Studio 2010 Command Prompt进行编译,这个会自动配置环境。
  2. 在执行第5步nmake -f ms\ntdll.mak前,进入D:\Program Files\Microsoft Visual Studio 10\VC\bin路径下(替换成自己的VC安装路径),命令行键入vcvars32,运行vcvars32.bat。然后再回到OpenSSL源码的目录,再执行第5步nmake -f ms\ntdll.mak或nmake -f ms\nt.mak

三、 OpenSSL加密与解密实践
OpenSSL安装完毕后,就可以使用它进行加密解密的操作。下面简单介绍一下工具的使用:生成**对、加密文件以及解密文件的操作。
1. 生成**对
运行生成目录下的openssl.exe,先生成一个1024的RSA**
openssl genrsa -out test.pem 1024
OpenSSL的编译、安装以及加密解密实践
这里-out指定生成文件的。需要注意的是这个文件包含了公钥和**两部分,也就是说这个文件即可用来加密也可以用来解密。后面的1024是生成**的长度。
openssl可以将这个文件中的公钥提取出来:
openssl rsa -in test.pem -pubout -out test_pub.pem
-in指定输入文件,-out指定提取生成公钥的文件名。至此,我们手上就有了一个公钥,一个私钥(包含公钥)。现在可以将用公钥来加密文件了。1024 RSA**对密文如下:
OpenSSL的编译、安装以及加密解密实践
OpenSSL的编译、安装以及加密解密实践
2. 文件的加密与解密
(1)首先在目录中创建一个try.txt的文本文件:
(2)然后利用此前生成的公钥加密文件
rsautl -encrypt -in try.txt -inkey signtool_pub.pem -pubin –out try_en.txt
-in指定要加密的文件,-inkey指定**,-pubin表明是用纯公钥文件加密,-out为加密后的文件。
(3)利用私钥解密文件
rsautl -decrypt -in try_en.txt -inkey signtool.pem -out try_de.txt
-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件。
OpenSSL的编译、安装以及加密解密实践
四、 API接口实现信息的加密与解密
下来介绍在程序如何利用之前生成的test.pem和test_pub.pem来进行信息的加密与解密(当然也可以直接利用openssl的API来生成**文件)。
在实际使用中,我们需要将PC与手机之间交互使用的鉴权码进行RSA加密后进行传输,保证其安全性。在VC程序中具体实现方式:首先需要在工程内包含openssl的include文件夹内的头文件和两个静态库libeay32.lib和ssleay32.lib,
1)配置属性——VC++目录——在include包含目录中新增"d:\openssl_lib\include"(存放编译后的库文件的目录中);
2)VC++目录——“Library files"选择中新增目录"d:\openssl_lib\lib”。
3)配置属性——链接器——输入——附加依赖项——libeay32.lib 和ssleay32.lib即可
接下来就是加密和解密相关API函数的调用了。主要用到4个API函数:
(1)PEM_read_RSA_PUBKEY(),读取公钥文件的内容;
PEM_read_RSAPrivateKey(),读取私钥文件的内容;
(2)RSA_public_encrypt(),使用公钥进行加密操作;
RSA_private_decrypt(),使用私钥进行解密操作。
加密函数如下:
OpenSSL的编译、安装以及加密解密实践
解密函数如下:
OpenSSL的编译、安装以及加密解密实践
在编译过程中遇到了1个问题:读取公钥内容的函数使用,openssl提供了2个函数接口PEM_read_RSA_PUBKEY()和PEM_read_RSAPublicKey(),根据私钥读取函数PEM_read_RSAPrivateKey()来说,公钥对应的读取函数应该使用PEM_read_RSAPublicKey(),但是使用该函数后返回指针p_rsa为空,程序报错。而使用PEM_read_RSA_PUBKEY()却能通过。查询了openssl官网上的文档发现,这和在私钥中提取公钥的格式有关,当时提取公钥是使用的命令为:openssl rsa -in test.pem -pubout -out test_pub.pem;其中的-pubout参数在官网上还可以使用-RSAPublicKey_out(1.0.0版本上可以使用该命令提取)代替,使用该参数提取的公钥对应使用的读取函数正是PEM_read_RSAPublicKey()。下图可以发现不同的提取公钥的方式,提取出来的公钥格式和内容都不相同。
-pubout参数提取的公钥:
OpenSSL的编译、安装以及加密解密实践
-RSAPublicKey_out参数提取的公钥:
OpenSSL的编译、安装以及加密解密实践