如何生成 Java PKCS12 存储以连接到常规 SSL 网站?

问题描述

我们使用常规购买的 SSL 证书通过 https 运行标准 Web API。我们的客户只是通过 https 访问它,证书通过认系统 RootCA 受信任。

新客户端正在使用 Java 通信服务器,该服务器需要 PKCS12 密钥库中的证书。我们如何从我们的 key/csr/crt/pem 文件生成 PKS12 密钥库?

我做了一些研究,大多数示例都需要私钥。我当然不想和客户分享我们的私钥。

是否可以在没有私钥的情况下创建 PKCS12 密钥库,类似于浏览器中的标准 RootCA?

谢谢,蓝豹

解决方法

是的。

虽然 PFX-now-PKCS12 的主要设计目的是将私钥证书链证书作为一个块存储或传输,并且最常用于也就是说,它能够存储一个或多个与任何私钥都不匹配的“单独”证书。而且您是正确的,想要连接到您的客户端应该在他们的信任库中理想地拥有您的服务器证书链的根证书,或者您的服务器证书本身,但绝对不是您的私钥。

openssl 可以实际创建这样的 PKCS12:

 openssl pkcs12 -export -in certfile.pem [-name $name] -nokeys -out blah.p12 
 # if you don't specify -name it defaults to 1 (the digit one) which can be mildly confusing
 # instead of being prompted for the password you can use -passout with several forms
 # described on the openssl man page,but consider the warning below

但是,如果他们使用标准(Sun/Oracle/OpenJDK)加密提供程序,则结果将无法在 Java 中工作,该加密提供程序(在 8+ 中)支持 PKCS12 中的单独证书作为 Java 中的“trustedCert”条目,仅当(每个) certbag 有一个特殊的 Sun 定义的属性,Java 提供者在创建这样的文件时会写入该属性,但 OpenSSL 没有。

改为在 8 中使用 Java 的 keytool:

jre8/bin/keytool -importcert -keystore blah.p12 -storetype pkcs12 -file $certfile [-alias $name]

或在 pkcs12 现在是默认值的 9+ 中:

jre9+/bin/keytool -importcert -keystore blah.p12 -file $certfile [-alias $name]

如果您不指定别名,则默认为 mykey。在这两种情况下,您都可以添加 -storepass $pw 以避免被提示输入密码,但结果密码将显示在您的屏幕上、您的 shell 或其他命令处理器的命令历史记录中,并且在大多数情况下其他进程在您的系统上同时运行的情况,(任何)这可能是一个安全问题,也可能不是。您还可以添加 -noprompt 以避免出现确认提示。

但是 user207421(大致)是正确的,使用这样的信任库可以破坏其他 SSL/TLS 连接,从他们的系统建立,至少从同一个 JVM,除非个别调用指定个人、单独的信任库,如果他们已经编码,他们就会知道如何处理(并要求)更简单的证书格式,例如 PEM。