【问题标题】:Java Certificate / Keystore ExceptionsJava 证书/密钥库异常
【发布时间】: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


【解决方案1】:

过去我在使用 ssl、java 和密钥库时也遇到过一些麻烦,我使用这个类将证书从某个服务器导入到密钥库中:
http://wiki.openkm.com/images/a/a0/InstallCert.java
https://code.google.com/p/java-use-examples/source/browse/trunk/src/com/aw/ad/util/InstallCert.java

它可以在互联网上的某些网站上找到。

导入证书的好工具是密钥库浏览器(适用于 Windows):
http://keystore-explorer.sourceforge.net/

希望这会有所帮助!

【讨论】:

  • 我已经尝试过 InstallCert 类(参见 #4)。不幸的是,我得到了由此生成的密钥库的数据不足异常。
  • 对不起 - 我错过了那部分。 :( 这是一种奇怪的行为。您可能仍会尝试使用密钥库浏览器。
  • 谢谢。我实际上一直在查看,并注意到密钥库之间存在不同的证书,因此我打算将它们全部加载到同一个密钥库中并尝试一下,但导出功能中似乎存在错误。我可以查看证书并看到详细信息有所不同,但是从多个密钥库导出证书会导出相同的第一个证书 n 次。
猜你喜欢
  • 2014-02-12
  • 2013-01-02
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
  • 2011-08-17
相关资源
最近更新 更多