证书未被WebSphere信任

8

我有一个Web应用程序,调用通过SSL进行保护的SOAP Web服务。(https://zzzzzzzzzzzz/xxxxx)。

服务器发送两个证书(根证书和叶子证书),因此我使用属性com.ibm.websphere.ssl.retrieveLeafCert导入这两个证书。

为了在WebSphere上启用SSL验证,我只需将证书添加到WebSphere:

SSL证书和密钥管理->密钥存储和证书->NodeDefaultTrustStore->签名者证书->从端口检索:

  • 主机:主机名
  • 端口:443
  • 别名:别名

问题是WebSphere不信任证书,并给出以下堆栈跟踪:

used by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking `https://------------------------------` : com.ibm.jsse2.util.j: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is: 
    java.security.cert.CertPathValidatorException: T`he certificate issued by CN=-------------------------------------------------------------------- is not trusted`; internal cause is: 
    java.security.cert.CertPathValidatorException: Certificate chaining error
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.6.0]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:56) ~[na:1.6.0]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:39) ~[na:1.6.0]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:527) ~[na:1.6.0]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1338) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1322) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:622) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.endpoint.ClientImpl.invokeWrapped(ClientImpl.java:354) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.jaxws.DispatchImpl.invoke(DispatchImpl.java:385) ~[cxf-rt-frontend-jaxws-2.7.4.jar:2.7.4]
    ... 100 common frames omitted
`Caused by: javax.net.ssl.SSLHandshakeException`: com.ibm.jsse2.util.j: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is: 
    java.security.cert.CertPathValidatorException: `The certificate issued by CN=--------------------------------------------------------- is not trusted`; internal cause is: 
    java.security.cert.CertPathValidatorException: Certificate chaining error
    at com.ibm.jsse2.o.a(o.java:8) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:549) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.kb.a(kb.java:355) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.kb.a(kb.java:130) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.lb.a(lb.java:135) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.lb.a(lb.java:368) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.kb.s(kb.java:442) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.kb.a(kb.java:136) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:495) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.SSLSocketImpl.h(SSLSocketImpl.java:223) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:724) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.SSLSocketImpl.startHandshake(SSLSocketImpl.java:81) ~[na:6.0 build_20130515]
    at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:8) ~[na:6.0 build_20130515]
    at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:20) ~[na:6.0 build_20130515]
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1043) ~[na:1.6.0]
    at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(b.java:85) ~[na:6.0 build_20130515]
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:168) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1282) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1233) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:195) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69) ~[cxf-api-2.7.4.jar:2.7.4]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1295) ~[cxf-rt-transports-http-2.7.4.jar:2.7.4]
    ... 110 common frames omitted
`Caused by: com.ibm.jsse2.util.j: PKIX path building failed:` java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is: 
    java.security.cert.CertPathValidatorException: T`he certificate issued by CN=--------------------------------------------  is not trusted`; internal cause is: 
    java.security.cert.CertPathValidatorException: Certificate chaining error
    at com.ibm.jsse2.util.h.b(h.java:39) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.util.h.b(h.java:21) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.util.g.a(g.java:1) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.pc.a(pc.java:36) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.pc.checkServerTrusted(pc.java:19) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.pc.b(pc.java:51) ~[na:6.0 build_20130515]
    at com.ibm.jsse2.lb.a(lb.java:65) ~[na:6.0 build_20130515]
    ... 128 common frames omitted
Caused by: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.
    at com.ibm.security.cert.PKIXCertPathBuilderImpl.engineBuild(PKIXCertPathBuilderImpl.java:411) ~[na:na]
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:258) ~[na:na]
    at com.ibm.jsse2.util.h.b(h.java:107) ~[na:6.0 build_20130515]
    ... 134 common frames omitted
Caused by: java.security.cert.CertPathValidatorException: The certificate issued by CN=-------------------------------------------------------
    at com.ibm.security.cert.BasicChecker.<init>(BasicChecker.java:111) ~[na:na]
    at com.ibm.security.cert.PKIXCertPathValidatorImpl.engineValidate(PKIXCertPathValidatorImpl.java:178) ~[na:na]
    at com.ibm.security.cert.PKIXCertPathBuilderImpl.myValidator(PKIXCertPathBuilderImpl.java:737) ~[na:na]
    at com.ibm.security.cert.PKIXCertPathBuilderImpl.buildCertPath(PKIXCertPathBuilderImpl.java:649) ~[na:na]
    at com.ibm.security.cert.PKIXCertPathBuilderImpl.buildCertPath(PKIXCertPathBuilderImpl.java:595) ~[na:na]
    at com.ibm.security.cert.PKIXCertPathBuilderImpl.engineBuild(PKIXCertPathBuilderImpl.java:357) ~[na:na]
    ... 136 common frames omitted
Caused by: java.security.cert.CertPathValidatorException: Certificate chaining error
    at com.ibm.security.cert.CertPathUtil.findIssuer(CertPathUtil.java:298) ~[na:na]
    at com.ibm.security.cert.BasicChecker.<init>(BasicChecker.java:108) ~[na:na]
    ... 141 common frames omitted

我在本地环境中使用Installcert.java简单测试了相同的代码,并通过-Djavax.net.ssl.trustStore=jssecacerts(jssecacerts是由InstallCert.java生成的文件)运行我的测试。

6个回答

12
感谢您提供的所有回复。通过以下配置,成功解决了java.security.cert.CertPathValidatorException:证书链接错误的问题。
  1. 发现在WebSphere中以下javax属性返回了null值。
    • javax.net.ssl.trustStore
    • javax.net.ssl.trustStorePassword
    • javax.net.ssl.trustStoreType

更多详情请参见此链接:

java - path to trustStore - set property doesn't work?

  1. 在WebSphere中进行以下属性配置:

    选择Servers > Application Servers > server_name > Process Definition > Java Virtual Machine > Custom Properties > New。

a) javax.net.ssl.trustStore = jre_install_dir\lib\security\cacerts

例如:C:\Program Files\WebSphere\AppServer\java\jre\lib\security\cacerts

b) javax.net.ssl.trustStorePassword = changeit (默认值)

c) javax.net.ssl.trustStoreType = jks
更多细节请参见此链接,

http://publib.boulder.ibm.com/infocenter/tivihelp/v2r1/index.jsp?topic=%2Fcom.ibm.isim.doc_6.0%2Finstalling%2Ftsk%2Ftsk_ic_ins_first_security_truststore.htm

在配置完成后,日志中可以看到证书已被添加到信任存储库中。
谢谢, Uday Nilajkar

1
谢谢 :) 这确实帮了很多 :) - Paritosh Ahuja
谢谢,这也是我的问题。我已经将所有证书放在 trust.p12 中,但是仍然握手失败。必须手动添加这些属性。 - Alex K.
IBM的链接已失效。 - John Berg

3

第一个链接坏了 :( - Enrique San Martín

0
你应该在配置中添加所有证书链。通常证书至少包含授权中心的根证书或类似证书链。
WAS 默认需要已签名的证书。

谢谢您的回复,您能提供更多解释吗?当我在本地环境中执行Installcert时,服务器向我呈现了两个证书(根证书和叶子证书),我将这两个证书导入到Node信任存储中。 - Nabil
主要问题不同:您的证书是受信任的还是自签名的?因为 WAS 默认情况下需要受信任的证书用于 SSL。 - Anton N
我的证书是受信任的。我已经查看了这两个 URL,但这并没有解决我的问题。无论我使用什么配置,我始终遇到相同的异常。 - Nabil
1
你看过这个解决方案吗:http://portal2portal.blogspot.com/2012/12/javasecuritycertcertpathvalidatorexcept.html - Anton N
类似问题:http://stackoverflow.com/questions/15928829/why-a-root-certificate-is-not-trusted-by-java-client-even-though-it-is-already - Anton N
显示剩余2条评论

0
问题在于证书路径构建器(Java Cert path API的一部分)无法在SSL握手期间构建证书链。在握手期间,SSL对等方主机向客户端发送其证书(身份),为了使客户端信任该特定证书,必须在客户端上建立信任链,这就是出现故障的原因。问题在于无法创建信任链,因为您的信任存储库(信任锚点)中缺少签名者证书和/或根证书。
请注意,PKIX信任管理器执行“信任范围”验证,这意味着您不需要在客户端上具有完整的证书链来满足与SSL对等方的信任关系,您只需要在信任存储库中拥有签名者/中间证书即可。实际上,如果您应该将叶子证书放入信任存储库,那也应该可以使事情正常工作,因为这表明您明确信任该特定证书,并且不需要证书链验证。

请您详细说明如何导入叶证书? - Ayan Biswas
一种方法是通过Web浏览器打开对等主机(URL)的位置,然后检查连接和用于该连接的对等证书,并选择“保存到文件”以将证书存储在本地计算机上。然后,您可以使用一些工具,例如Java的keytool或IBM的iKeyMan将其导入到本地密钥库中。 - Robert Höglund

0

也许你应该看一下以下技术笔记

如果你处于某个修补程序级别,你可以将值com.ibm.websphere.ssl.retrieveLeafCert设置为true,并在从端口检索时获取叶证书。


我已经这样做了,我添加了根证书和叶子证书。但问题是,当我使用 IkeyMan 探索证书内容时,发现该内容与在我的本地环境中执行调用时有效的本地证书完全相同。 - Nabil

0

以下是导入证书到JVM进行HTTPS WS调用的步骤:

A) 获取要导入的证书

  1. 每个浏览器显示证书的方式不同,但它们通常相似。在浏览器的URL栏上,通常有一个区域可以点击以显示SSL证书信息。例如,您可能会看到状态栏中的挂锁,单击挂锁会打开证书信息。打开证书信息后,单击“认证路径”信息。通常会有一种方法来导出每个签名证书(受信任的根)。以"Base-64编码X.509(.CER)"格式导出认证者。该格式的导出文件将是一个带有“BEGIN CERTIFICATE”和“END CERTIFICATE”行的ASCII文本文件。一旦您已经导出了签署远程服务器SSL证书的证书,就可以将它们导入JVM。

B) 导入证书

  1. 启动ikeyman工具。该工具(ikeyman.bat或ikeyman.sh)位于WAS_HOME\bin目录下。
  2. 从密钥数据库文件菜单中选择“打开”。
  3. 在密钥数据库类型中,选择JKS。
  4. 在文件名字段中,输入cacerts。
  5. 在位置字段中,输入WAS_HOME\java\jre\lib\security。
  6. 在密码提示窗口中,输入密钥库的密码并在确认密码窗口中再次输入密码。默认密码为changeit。点击“确定”。
  7. 将您为LDAP服务器创建的证书添加到此证书存储区中。
  8. 在主窗口中,在密钥数据库内容区域中,从列表中选择“签名者证书”。 点击“添加”。
  9. 在证书文件名字段中,浏览并定位为LDAP服务器创建的服务器证书文件,该文件以二进制DER数据格式保存。验证位置字段中是否显示了适当的目录。 点击“确定”。
  10. 在提示中,为此证书键入一个标签。例如,键入LDAPCA。 点击“确定”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接