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所示。
图 10-13 OpenSSL系统变量配置
请读者朋友注意,如果使用Windows Vista或Windows 7操作系统使用OpenSSL相关命令时,必须使用管理员身份。
图 10-14 OpenSSL命令行操作
❑工作目录
打开OpenSSL配置文件openssl.cfg(%OpenSSL_Home%\bin\openssl.cfg),找到配置[CA_default],如图10-15所示。
图 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所示。
图 10-16 构建随机数文件
请读者朋友注意,如果在Windows Vista或Windows 7中未能使用管理权限执行上述命令,将无法创建随机数文件,如图10-17所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 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所示。
图 10-30 客户证书转换
这时我们需要输入客户证书密码“123456”。
至此,我们完成了双向认证的所需的全部证书。我们将在后续章节中介绍如何构建基于双向认证的网络应用。