我收到 SSL 握手异常错误:PKIX“路径不链接”(在此处描述)。我通过使用 openssl 导入证书链来修复它:
openssl s_client -host www.envmgr.com -port 443 -showcerts > cert_chain.crt
并将其安装到我的 JDK 的密钥库中:
keytool -import -alias envmgrchain -file cert_chain.crt -keystore cacerts -storepass changeit
这行得通。万岁。问题是我们将把我们的应用程序放在像 rackspace 或 AWS 这样的云服务器上,我认为我们很有可能无法修改 JVM 的密钥库来添加这个链。
我想,“没问题,我会以编程方式将此证书链添加到密钥库”,所以我将它从我的 JVM 中删除:
keytool -delete -alias envmgrchain -keystore cacerts -storepass changeit
并添加了以下代码:
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
//Create an empty keystore that we can load certificate into
trustStore.load(null);
InputStream fis = new FileInputStream("cert_chain.crt");
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while(bis.available()>0) {
Collection<? extends Certificate> certs = cf.generateCertificates(bis);
Iterator<? extends Certificate> iter = certs.iterator();
//Add each cert in the chain one at a time
for(int i=0; i<certs.size(); i++) {
Certificate cert = iter.next();
String alias = "chaincert"+((i>0)?i:"");
trustStore.setCertificateEntry(alias, cert);
}
}
bis.close();
fis.close();
//Add custom keystore to TrustManager
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
SSLContext ctx = SSLContext.getInstance("TLSv1");
ctx.init(null, tmf.getTrustManagers(), null);
但是当我运行它时,PKIX 错误再次出现。上面的代码不等同于 keytool -import 吗?我觉得我要么错误地将证书添加到 KeyStore,要么我没有以正确的方式将 Keystore 安装到 TrustManager 中。
仅供参考:我也试图通过实现 X509TrustManager 来解决这个问题。