【发布时间】:2014-03-11 04:33:18
【问题描述】:
当尝试在 Java SOAP 客户端中实现密钥库以访问 WS 时,出现异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我们确定造成这种情况的原因是 CA (DigiSign) 不在 Java 受信任的 CA 中。 最初,我使用了我们的一位高级工程师给我的两个证书,并通过 keytool 将它们组合起来:
keytool.exe -v -alias digicert_3 -import -file DigiCertHighAssuranceCA-3.pem -keystore mykeystore.jks
keytool.exe -v -alias digicert_root -import -file DigiCertHighAssuranceEVRootCA.pem -keystore mykeystore.jks
然后我将 keystore.jks 文件复制到 src/main/resources 下的 Eclipse 项目中。
但是,现在我遇到了其他例外情况。我尝试了多种将证书加载到密钥库中的方法,但遇到了各种异常。
以下是我尝试实现密钥库的不同方式(一次一个):
//Load keystore from project resource
KeyStore keyStore = KeyStore.getInstance("JKS");
//Keystore created using two individual PEM certs
//Exception: java.io.IOException: Keystore was tampered with, or password was incorrect
keyStore.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("mykeystore_PEM.jks"), "password".toCharArray());
//Keystore created with two certs combined into a single file
//Exception: java.io.IOException: Keystore was tampered with, or password was incorrect
keyStore.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("mykeystore_Com.jks"), "password".toCharArray());
//Keystore created using two individual DER cert calls
//Exception: java.io.IOException: DerInputStream.getLength(): lengthTag=127, too big.
keyStore.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("mykeystore_DER.jks"), "password".toCharArray());
//Keystore created using InstallCert
//Exception: java.security.cert.CertificateParsingException: java.io.IOException: insufficient data
keyStore.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jssecacerts"), "changeit".toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] trustManagers = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(trustManagers);
conduit.setTlsClientParameters(tlsParams);
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setReceiveTimeout(32000);
conduit.setClient(httpClientPolicy);
1 & 2.) 我已经验证并再次检查了密码,所以我不知道为什么前两个失败并出现该错误。
3.) 关于长度的第三个例外,我读到它通常是 END CERTIFICATE 行之后的数据问题。我已经尝试在之后使用单个空行(给出“太大”异常)或最后一行是 END CERTIFICATE 行(给出其他一些异常)。
4.) 从here 运行 InstallCert 类,系统提示我获取一个证书,它会显示在密钥库中。
知道为什么我的密钥库不工作吗?是 Java 代码的问题,还是证书/密钥库没有正确生成?
【问题讨论】:
-
KeyStore实例加载后会做什么? -
@Bruno 在
keyStore被加载后,我创建了一个TrustManagerFactory对象并将 keyStore 作为参数传递给它的 init 方法:trustFactory.init(keyStore)。 -
您确定最终会将信任管理器传递给您的 WS 客户端吗?
-
@Bruno 是的,据我所知,它正在通过管道的
setClient方法通过 trustFactory 传回。我会将完整的代码附加到我的原始问题中,以防其中有不匹配的内容。在我看来是正确的。 -
有没有人解决这个问题?我也在尝试从 src/main/resources 目录读取 keystore.jks 文件并面临“异常:java.io.IOException:DerInputStream.getLength():lengthTag=127,太大。”
标签: java eclipse ssl certificate