本文描述了 Java7 中 keytool 工具的使用方法,并结合具体代码片段,向读者阐述如何使用 JSSE 提供的 API 进行安全套接字编程,以及如何进行 SSL/TSL 程序调试等技巧,让读者可以学以致用。
原文地址: Java 安全套接字编程以及 keytool 使用最佳实践。 作者: 赵映洁
概述
利用 Java 的 JSSE(Java Secure Socket Extension)技术,我们可以方便的编写安全套接字程序,关于 JSSE 的介绍,可以参阅 Oracle 网站提供的 JSSE 指导。程序编写过程中,我们需要将数字证书应用到代码中。通常在正式的产品开发中,我们可以支付一定的费用,向正规认证机构,例如:Verisign、Geotrust、Thawte 等申请。
如果只是为了实验,我们还可以使用 Java 自带的 keytool 工具来制作证书。keytool 是密钥和证书管理工具,生成的密钥或证书,存放在 jks(Java Key Store) 格式的文件里。从用途上来说,jks 格式的文件常用于:
1) 存储非对称密钥对以及数字证书的证书库;
2) 存储信任证书列表的信任库。
注意:不同版本的 Java 自带的 keytool 命令行参数可能会略有不同。相比于 Java6,在 Java7 中 keytool 工具有如下改动:
-export 选项改名为 -exportcert
-genkey 选项改名为 -genkeypair
-import 选项改名为 – importcert
-keyclone 选项被废弃
-identitydb 选项被废弃
-selfcert 选项被废弃
下面将以 Java7 中的 keytool 为例,对常见的用法进行说明。
使用 keytool 制作证书库以及信任库
生成非对称密钥以及自签发证书
命令:keytool -genkeypair -alias TEST_ROOT -keystore test_root.jks
解释:生成一对密钥以及一个自签发证书,其中私钥和证书以别名 TEST_ROOT 存储在 test_root.jks 文件中。
注意:使用上述命令时,命令行会交互的需要手动填写密码、CN、OU 等信息。也可以直接在命令行指定这些参数,详情见 参考资料中列出的 keytool 使用帮助。
生成证书请求文件
命令:keytool -certreq -file test_server.csr -alias TEST_SERVER -keystore test_server.jks
解释:将别名为 TEST_SERVER 的公钥和一些个人信息从 test_server.jks 文件中导出,作为证书请求文件。
#####签发证书
命令:keytool -gencert -infile test_server.csr -outfile test_server.cer -alias TEST_ROOT -keystore TEST_ROOT.jks
解释:使用别名为 TEST_ROOT 的私钥为 test_server.csr 签发证书,并保存到 test_server.cer 文件中。
从 jks 文件中导出证书
命令:keytool -exportcert -alias TEST_ROOT -file test_root.cer -keystore test_root.jks
解释:从 test_root.jks 文件中导出别名为 TEST_ROOT 的证书并存放在 test_root.cer 文件中。
导入信任证书到 jks 文件
命令:keytool -importcert -alias TEST_ROOT -file test_root.cer -keystore TEST_SERVER.jks
解释:将证书 test_root.cer 以别名 TEST_ROOT 导入 TEST_SERVER.jks 中。
注意:这里的目标 jks 文件里不含有指定的别名,此时的导入条目才会以 trustedCertEntry 信任证书的形式保存。
导入签发证书到 jks 文件 ( 更新证书 )
命令:keytool -importcert -alias TEST_SERVER -file test_server.cer -keystore TEST_SERVER.jks
解释:将证书 test_server.cer 更新到已存在别名 TEST_SERVER 的 TEST_SERVER.jks 文件中
注意:这里的命令和上述导入信任证书的命令在形式上完全一样,但作用不同。
- 这里的目标 jks 文件里要含有指定的别名,这样 keytool 工具才会理解命令为更新证书,并以 PrivateKeyEntry 的形式保存。
- 在更新被签发证书之前,一定要先将相应的 CA 证书,导入进 jks 文件,否则会报错“keytool 错误 : java.lang.Exception: 无法从回复中建立链”。
打印证书内容
命令:keytool – printcert – v – file test_server.cer
解释:将证书 test_server.cer 的内容打印出来
注意:也可以使用 -sslserver ip:port 的参数,直接从网络上打印出某个 ssl server 提供的证书的内容,详情见 参考资料中列出的 keytool 使用帮助。
显示 jks 文件里的内容
命令:keytool – list – v – keystore test_server.jks
解释:显示 test_server.jks 里存储的所有条目
注意:这里会要求提供 jks 文件的密码,如果不输入,也可以显示出所有条目信息,但会提示“存储在密钥库中的信息的完整性尚未得到验证!”
从 jks 文件删除条目
命令:keytool -delete -alias TEST_ROOT -keystore test_server.jks
解释:从 test_server.jks 中删除别名为 TEST_ROOT 的条目