使用 Keytool 将 P7B 证书文件导入 Java 密钥库指南
1. 前言
在开发 Java 生产环境应用时,我们经常需要配置 HTTPS、启用安全的出站通信或管理信任库(Truststore)。Keytool 是处理密钥和证书的标准工具,也是管理 Java 密钥库(Keystore) 的核心工具。
在本教程中,我们将重点介绍一项特定任务:使用 keytool 将 .p7b 证书文件导入到 Java 密钥库中。
2. 理解 P7B (PKCS#7) 格式
在深入导入 P7B 文件的步骤之前,先了解一下 PKCS#7 格式 是非常有必要的。
在密码学中,PKCS#7 是一种用于存储经加密签名或加密数据的标准语法。
该格式的一种常见用途是存储 SSL 证书。通常,证书包(Certificate Bundle)会以 .p7b 文件格式进行存储和共享。
2.1. 证书包
在创建用于开发环境的 自签名(Self-signed) 证书时,通常只需要一个私钥和一个包含公钥的自签名证书即可。然而,当开发需要通过互联网访问的生产应用时,我们通常需要证书由受信任的证书颁发机构(CA)进行验证。
浏览器通过验证网站证书来验证该网站的合法性。 每个网站都会出示其自身的证书,连同指向中间证书链的信息,最终指向 CA 的根证书。由于浏览器信任该 CA,因此任何出示经验证的证书(且具有通往根 CA 证书的清晰证书链)的网站都会被视为有效。
一旦证书通过 CA 验证,CA 通常会提供一个证书链,其中包括其自身的根证书和零个或多个中间证书。该证书链以证书包的形式提供,有时表现为 .p7b 文件。
2.2. P7B 格式
P7B 文件是一个可以存储一个或多个证书的 PKCS#7 容器。 它可以采用二进制 DER 格式或 Base64 PEM 格式进行编码。
在使用 Java 服务器(如 Tomcat)时,我们需要确保包中的所有证书都已导入到密钥库中,以证明我们证书的有效性。
现代设备上的浏览器都能识别经 CA 验证的证书。在证书验证过程中,CA 通常会共享我们网站已签名的公钥证书以及证书链(即证书包)。
有时,证书包会以 .p7b 为扩展名。需要注意的是,根据编码方式的不同,其内容可能无法直接在纯文本编辑器中轻松读取。因此,我们需要一些工具来处理这些证书并将其导入到密钥库中。
3. 准备 P7B 文件
了解了 P7B 格式后,让我们开始操作。
在导入证书包之前,我们需要一个包含证书包的文件。 由于我们没有现成的 CA 提供的 .p7b 文件,我们将使用 Baeldung.com 的公钥证书作为示例。
首先,下载证书链并将其转换为 P7B 文件格式。
3.1. 下载证书包
大多数现代浏览器都允许将证书导出为 PKCS#7 格式的文件。不过,我们将使用 Linux 终端上的 openssl 命令行工具来完成:
该命令会打印出多个证书以及关于每个证书的其他信息。每个证书都可以通过其开头和结尾标记轻松识别:
现在,我们可以复制每个证书(包括标记),并将它们分别存储为 .pem 文件。这样我们就得到了三个文件:site.pem、intermediate.pem 和 root.pem。
接下来,利用它们创建一个 .p7b 证书包:
最后,我们可以验证包中是否包含了所有需要的证书:
可以看到输出了预期的三个证书。
3.2. 导入 P7B 文件时遇到的问题
现在我们有了一个有效的 .p7b 格式证书包,让我们用 keytool 检查一下:
该命令可以清晰地打印出这三个证书的信息。
现在尝试直接导入:
输出显示了一个错误:
证书导入失败的原因是 keytool -importcert 要求输入文件必须恰好包含一个 X.509 PEM 或 DER 编码的证书。
4. 导入 P7B 文件
我们发现使用 keytool 直接导入证书包会存在问题。解决方案是将证书包拆分为独立的证书,然后逐一进行导入。
4.1. 转换为 PEM 编码
要将证书包拆分为独立的 PEM 文件,首先需要将 PKCS#7 格式的包转换为 PEM 编码的包:
这将生成一个包含一个或多个 X.509 证书的 PEM 文件:
现在可以使用 keytool 导入证书了。
4.2. 导入 PEM 证书包
由于文件已转换为 keytool 导入选项所兼容的格式,我们可以执行导入操作:
该命令会要求设置密钥库密码,并询问是否信任该证书。成功后的输出如下:
这将以别名 site 导入站点证书。
如果还需要在同一个密钥库中包含中间证书和根证书,则需要分别导入它们。 我们可以从 site-chain.pem 中复制每个证书(包括开始和结束标记),并将它们分别存储为 .pem 文件。现在我们有了两个额外的文件:intermediate.pem 和 root.pem。
使用相同的命令,配合不同的输入文件和别名,即可导入根证书和中间证书:
4.3. 验证导入结果
现在所有证书已导入,让我们进行验证:
该命令会要求输入之前设置的密码,然后显示所有已导入证书的详细信息。在输出的开头,我们会看到:
完成,我们的密钥库现在可以使用了。
5. 总结
在本文中,我们探讨了 keytool 如何处理 PKCS#7 (.p7b) 格式的证书包。虽然这些文件可以包含完整的证书链,但它们并不总是能直接导入。
我们了解到 keytool 要求输入的是 DER 或 PEM 格式的 X.509 证书,而不是像 PKCS#7 这样的容器格式。将 .p7b 证书包转换为独立的证书文件,可以确保导入过程顺利且可控。