10.3.2 OpenSSL证书管理

OpenSSL(http://www. openssl.org/)是一个开放源代码软件包,由Eric A.Young和Tim J.Hudson等人编写,实现了SSL及相关加密技术,是最常用的证书管理工具。OpenSSL功能远胜于KeyTool,可用于根证书、服务器证书和客户证书的管理。相关操作可以参考官方文档(http://www.openssl.org/docs/apps/openssl.html)。

我们可以在OpenSSL官网下载页面(http://www.openssl.org/source/)下载最新的源码(目前最新版本为0.9.8l),下载后需对源码包进行编译后方能使用。OpenSSL官网提供了Windows版的二进制发行版地址(http://www.slproweb.com/products/Win32OpenSSL.html),我们可以在该页面下载最新的Windows版OpenSSL。

本文以Windows版OpenSSL为例,演示如何构建数字证书。

1.准备工作

Windows版OpenSSL分为Win32和Win64共2个平台版本,请读者朋友注意选择合适的发行版,本文选用Win32 OpenSSL v0.9.8l Light演示数字证书构建相关操作。

有关Windows版OpenSSL安装操作与一般软件安装并无差别,需要读者朋友注意的是OpenSSL的相关配置。

❑环境变量

为了在命令行下方便使用OpenSSL,我们需要在Windows环境变量对话框中对OpenSSL进行设置,如图10-13所示。

设置系统变量OpenSSL_Home,并将其指向OpenSSL的安装目录(C:\OpenSSL)。同时,将其执行目录(%OpenSSL_Home%\bin;)加入系统变量Path中。完成上述操作后,在命令行下执行OpenSSL命令,如图10-14所示。

figure_0355_0091

图 10-13 OpenSSL系统变量配置

请读者朋友注意,如果使用Windows Vista或Windows 7操作系统使用OpenSSL相关命令时,必须使用管理员身份。

figure_0355_0092

图 10-14 OpenSSL命令行操作

❑工作目录

打开OpenSSL配置文件openssl.cfg(%OpenSSL_Home%\bin\openssl.cfg),找到配置[CA_default],如图10-15所示。

figure_0355_0093

图 10-15 OpenSSL初始配置

注意变量dir,它指向的是CA工作目录,本文将路径D:/ca作为CA工作目录,对变量dir做相应修改。对于其他变量,我们无需修改。

建立CA工作目录后,我们需要构建一些子目录,用于存放证书、密钥等。完整命令如代码清单10-8所示。

代码清单10-8 构建CA子目录


echo构建已发行证书存放目录certs

mkdir certs

echo构建新证书存放目录newcerts

mkdir newcerts

echo构建私钥存放目录private

mkdir private

echo构建证书吊销列表存放目录crl

mkdir crl


我们将在创建证书时用到上述目录,最终在certs目录中获得证书文件。

接下来,我们需要构建一些文件,完整命令如代码清单10-9所示。

代码清单10-9 构建相关文件


echo构建索引文件index.txt

echo 0>index.txt

echo构建序列号文件serial

echo 01>serial


完成上述操作后,我们就可以进行证书的构建和签发工作了。

2.构建根证书

在构建根证书前,需要构建随机数文件(.rand),完整命令如代码清单10-10所示。

代码清单10-10 构建随机数


echo构建随机数private/.rand

openssl rand-out private/.rand 1000


各参数的含义如下所示:

rand 随机数命令。

-out 输出文件路径,这里将随机数文件输出到private目录下。

这里的参数1000,指用来产生伪随机字节数。

上述命令执行结果如图10-16所示。

figure_0356_0094

图 10-16 构建随机数文件

请读者朋友注意,如果在Windows Vista或Windows 7中未能使用管理权限执行上述命令,将无法创建随机数文件,如图10-17所示。

figure_0356_0095

图 10-17 构建随机数文件失败

OpenSSL通常使用PEM(Privacy Enbanced Mail,隐私增强邮件)编码格式保存私钥。

接下来,我们需要构建根证书密钥(ca.key.pem),完整命令如代码清单10-11所示。

代码清单10-11 构建根证书私钥


echo构建根证书私钥private/ca.key.pem

openssl genrsa-aes256-out private/ca.key.pem 2048


各参数的含义如下所示:

genrsa 产生RSA密钥命令。

-aes256 使用AES算法(256位密钥)对产生的私钥加密。可选算法包括DES、DESede、IDEA和AES。

-out 输出路径,这里指private/ca.key.pem。

这里的参数2048,指RSA密钥长度位数,默认长度为512位。

上述命令执行结果,如图10-18所示。

figure_0357_0096

图 10-18 构建根证书私钥

这时我们需要输入根证书密码“123456”。

完成密钥构建操作后,我们需要生成根证书签发申请文件(ca.csr),完整命令如代码清单10-12所示。

代码清单10-12 生成根证书签发申请


echo生成根证书签发申请private/ca.csr

openssl req-new-key private/ca.key.pem-out private/ca.csr-subj"/C=CN/ST=BJ/L=BJ/O=zlex/OU=zlex/CN=*.zlex.org"


各参数的含义如下所示:

req 产生证书签发申请命令。

-new 表示新请求。

-key 密钥,这里为private/ca.key.pem文件。

-out 输出路径,这里为private/ca.csr文件。

-subj 指定用户信息,这里使用泛域名“*.zlex.org”作为用户名。

上述命令执行结果,如图10-19所示。

这时我们需要输入根证书密码“123456”。

得到根证书签发申请文件后,我们可以将其发送给CA机构签发。当然,我们也可以自行签发根证书。签发根证书完整命令如代码清单10-13所示。

figure_0358_0097

图 10-19 生成根证书签发申请

代码清单10-13 签发根证书


echo签发根证书private/ca.cer

openssl x509-req-days 10000-sha1-extensions v3_ca-signkey private/ca.key.pem-in private/ca.csr-out certs/ca.cer


各参数的含义如下所示:

x509 签发X.509格式证书命令。

-req 表示证书输入请求。

-days 表示有效天数,这里为10000天。

-sha1 表示证书摘要算法,这里为SHA1算法。

-extensions 表示按OpenSSL配置文件v3_ca项添加扩展。

-signkey 表示自签名密钥,这里为private/ca.key.pem。

-in 表示输入文件,这里为private/ca.csr。

-out 表示输出文件,这里为certs/ca.cer。

上述命令执行结果,如图10-20所示。

figure_0358_0098

图 10-20 签发根证书

这时我们需要输入根证书密码“123456”。

OpenSSL产生的数字证书不能在Java语言环境中直接使用,需要将其转化为PKCS#12编码格式。完整命令如代码清单10-14所示。

代码清单10-14 根证书转换


echo根证书转换private/ca.p12

openssl pkcs12-export-cacerts-inkey private/ca.key.pem-in certs/ca.cer-out certs/ca.p12


各参数的含义如下所示:

pkcs12 PKCS#12 编码格式证书命令。

-export 表示导出证书。

-cacerts 表示仅导出CA证书。

-inkey 表示输入密钥,这里为private/ca.key.pem。

-in 表示输入文件,这里为certs/ca.cer。

-out 表示输出文件,这里为certs/ca.p12。

上述命令执行结果,如图10-21所示。

figure_0359_0099

图 10-21 根证书转换

这时我们需要输入根证书密码“123456”。

个人信息交换文件(PKCS#12)可以作为密钥库或信任库使用,我们可以通过KeyTool查看该密钥库的详细信息。完整命令如代码清单10-15所示。

代码清单10-15 查看密钥库信息


keytool-list-keystore certs/ca.p12-storetype pkcs12-v-storepass 123456


注意,这里参数-storetype值为“pkcs12”。上述命令执行结果如图10-22所示。

figure_0359_0100

图 10-22 查看密钥库信息

现在,我们已经构建了根证书(ca.cer),我们可以使用根证书签发服务器证书和客户证书。

3.构建服务器证书

服务器证书的构建与根证书构建相似,首先需要构建私钥。完整命令如代码清单10-16所示。

代码清单10-16 构建服务器私钥


echo构建服务器私钥private/server.key.pem

openssl genrsa-aes256-out private/server.key.pem 2048


各参数的含义如下所示:

genrsa 产生RSA密钥命令。

-aes256 使用AES算法(256位密钥)对产生的私钥加密。可选算法包括DES、DESede、IDEA和AES。

-out 输出路径,这里指private/server.key.pem。

这里的参数2048,指RSA密钥长度位数,默认长度为512位。

上述命令执行结果,如图10-23所示。

figure_0360_0101

图 10-23 产生服务器证书密钥

这时我们需要输入服务器证书密码“123456”。

完成服务器证书密钥构建后,我们需要产生服务器证书签发申请。完整命令如代码清单10-17所示。

代码清单10-17 生成服务器证书签发申请


echo生成服务器证书签发申请private/server.csr

openssl req-new-key private/server.key.pem-out private/server.csr-subj"/C=CN/ST=BJ/L=BJ/O=zlex/OU=zlex/CN=www.zlex.org"


各参数的含义如下所示:

req 产生证书签发申请命令。

-new 表示新请求。

-key 密钥,这里为private/ca.key.pem文件。

-out 输出路径,这里为private/ca.csr文件。

-subj 指定用户信息,这里使用域名“www.zlex.org”作为用户名。

上述命令执行结果,如图10-24所示。

figure_0360_0102

图 10-24 生成服务器证书签发申请

这时我们需要输入服务器证书密码“123456”。

我们已经获得了根证书,可以使用根证书签发服务器证书。完整命令如代码清单10-18所示。

代码清单10-18 签发服务器证书


echo签发服务器证书private/server.cer

openssl x509-req-days 3650-sha1-extensions v3_req-CA certs/ca.cer-CAkey

private/ca.key.pem-CAserial ca.srl-CAcreateserial-in private/server.csr-out

certs/server.cer


各参数的含义如下所示:

x509 签发X.509格式证书命令。

-req 表示证书输入请求。

-days 表示有效天数,这里为3650天。

-sha1 表示证书摘要算法,这里为SHA1算法。

-extensions 表示按OpenSSL配置文件v3_req项添加扩展。

-CA 表示CA证书,这里为certs/ca.cer。

-CAkey 表示CA证书密钥,这里为private/ca.key.pem。

-CAserial 表示CA证书序列号文件,这里为ca.srl。

-CAcreateserial 表示创建CA证书序列号。

-in 表示输入文件,这里为private/server.csr。

-out 表示输出文件,这里为certs/server.cer。

上述命令执行结果,如图10-25所示。

figure_0361_0103

图 10-25 签发服务器证书

这时我们需要输入服务器证书密码“123456”。

这里我们同样需要将OpenSSL产生的数字证书转化为PKCS#12编码格式。完整命令如代码清单10-19所示。

代码清单10-19 服务器证书转换


echo服务器证书转换private/server.p12

openssl pkcs12-export-clcerts-inkey private/server.key.pem-in

certs/server.cer-out certs/server.p12


各参数的含义如下所示:

pkcs12 PKCS#12 编码格式证书命令。

-export 表示导出证书。

-clcerts 表示仅导出客户证书。

-inkey 表示输入密钥,这里为private/server.key.pem。

-in 表示输入文件,这里为certs/ca.cer。

-out 表示输出文件,这里为certs/server.p12。

上述命令执行结果,如图10-26所示。

figure_0361_0104

图 10-26 服务器证书转换

这时我们需要输入服务器证书密码“123456”。

现在,我们已经构建了服务器证书(server.cer),并可使用该证书构建基于单向认证的网络交互平台。

4.构建客户证书

客户证书的构建与服务器证书构建基本一致,首先需要构建私钥。完整命令如代码清单10-20所示。

代码清单10-20 产生客户私钥


echo产生客户私钥private/client.key.pem

openssl genrsa-aes256-out private/client.key.pem 2048


各参数的含义如下所示:

genrsa 产生RSA密钥命令。

-aes256 使用AES算法(256位密钥)对产生的私钥加密。可选算法包括DES、DESede、IDEA和AES。

-out 输出路径,这里指private/client.key.pem。

这里的参数2048,指RSA密钥长度位数,默认长度为512位。

上述命令执行结果,如图10-27所示。

figure_0362_0105

图 10-27 产生客户密钥

这时我们需要输入客户证书密码“123456”。

完成客户证书密钥构建后,我们需要产生客户证书签发申请。完整命令如代码清单10-21所示。

代码清单10-21 生成客户证书签发申请


echo生成客户证书签发申请client.csr

openssl req-new-key private/client.key.pem-out private/client.csr-subj

"/C=CN/ST=BJ/L=BJ/O=zlex/OU=zlex/CN=zlex"


各参数的含义如下所示:

req 产生证书签发申请命令。

-new 表示新请求。

-key 密钥,这里为private/client.key.pem文件。

-out 输出路径,这里为private/client.csr文件。

-subj 指定用户信息,这里使用“zlex”作为用户名。

上述命令执行结果,如图10-28所示。

figure_0363_0106

图 10-28 生成客户证书签发申请

这时我们需要输入客户证书密码“123456”。

我们已经获得了根证书,可以使用根证书签发客户证书(client.cer)。完整命令如代码清单10-22所示。

代码清单10-22 签发客户证书


echo签发客户证书certs/client.cer

openssl ca-days 3650-in private/client.csr-out certs/client.cer-cert

certs/ca.cer-keyfile private/ca.key.pem


各参数的含义如下所示:

ca 签发证书命令。

-days 表示证书有效期,这里为3650天。

-in 表示输入文件,这里为private/client.csr。

-out 表示输出文件,这里为certs/server.cer。

-cert 表示证书文件,这里为certs/ca.cer。

-keyfile 表示根证书密钥文件,这里为private/ca.key.pem。

上述命令执行结果,如图10-29所示。

figure_0363_0107

图 10-29 签发客户证书

这时我们需要输入客户证书密码“123456”,并同意签发证书。

最后,我们需要将获得客户证书转化Java语言可以识别的PKCS#12编码格式。完整命令如代码清单10-23所示。

代码清单10-23 客户证书转换


echo客户证书转换certs/client.p12

openssl pkcs12-export-inkey private/client.key.pem-in certs/client.cer-out certs/client.p12


各参数的含义如下所示:

pkcs12 PKCS#12 编码格式证书命令。

-export 表示导出证书。

-clcerts 表示仅导出客户证书。

-inkey 表示输入密钥,这里为private/client.key.pem。

-in 表示输入文件,这里为certs/client.cer。

-out 表示输出文件,这里为certs/client.p12。

上述命令执行结果,如图10-30所示。

figure_0364_0108

图 10-30 客户证书转换

这时我们需要输入客户证书密码“123456”。

至此,我们完成了双向认证的所需的全部证书。我们将在后续章节中介绍如何构建基于双向认证的网络应用。