Java 7(充当客户端)使用在Java 6中工作的密钥库和信任库的SSL握手失败

我正在进行JBoss AS 5.1到7.4以及Java 6到7的迁移,并且获得握手失败。

密钥库和信任库是我们在Java 6中成功使用的密钥库和信任库。

我已经写了一些测试来缩小问题范围,它绝对不是JBoss,而是Java 7。

启用S​​SL日志记录后,我明白了:

17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) %% Invalidated: [Session-2, SSL_RSA_WITH_RC4_128_SHA] 17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, SEND TLSv1 ALERT: fatal, description = certificate_unknown 17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, WRITE: TLSv1 Alert, length = 2 17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, called closeSocket() 17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors 17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, called close() 17:44:30,042 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, called closeInternal(true) 

有一些线程涉及这个(或类似的)问题,人们建议用不同的参数重新创建证书或信任商店。 我宁愿不走这条路,因为我最近没有成功,试图为同一个webservice的不同帐户创建更多这样的密钥库和信任库。

由于我们在Java 6中使用这些旧的(密钥库和信任库),我想尽可能保留它们。

看来问题可能是由于Java 7在检查信任库证书链方面更紧张?

是否可以设置一些标志来放松检查,使其表现得像Java 6?

我不能100%确定的是如何解释失败消息:我认为它告诉我它是我的机器(不是移除服务器),不满足远程机器是安全的。 那是对的吗?

任何帮助/想法赞赏!

================================================== ========

正如所建议的,已经添加了PEM(带链),在访问WS URL时从firefox导出到信任库。 这不会使它握手,但会稍微改变失败。

 *** %% Invalidated: [Session-1, SSL_RSA_WITH_RC4_128_SHA] main, SEND TLSv1 ALERT: fatal, description = certificate_unknown main, WRITE: TLSv1 Alert, length = 2 [Raw write]: length = 7 0000: 15 03 01 00 02 02 2E ....... main, called closeSocket() main, handling exception: 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 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 at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) 

================================================== ============

另外,正如其他线程所建议的那样,我编写了另一个使用不validation证书链的TrustManager的测试,并使用我原来的信任库运行它。

这个测试能够连接,从而表明我的机器validation远程机器是唯一的问题,而且我的密钥库很好。

但是,我不能将这种方法用于我们实际的Web服务客户端,因为它使用Sun RPC库,并且连接发生在代码深处,所以我无法触及它。

首先,是的,例外情况表明您机器中的Java SSL模块不信任从服务器收到的身份certificate(证书)。

是的,Java 7进行了更严格的检查。 可能会有更多,但我确定的是,它不允许子证书的有效期在父/ CA证书之后结束(或在之前开始,但在实践中不会发生)。 请参阅PKIX Path不与Windows环境中的任何信任锚错误链接,该错误表明它是一个错误并将被修复。

要检查:如果服务器是Web服务器,您可以使用浏览器访问任何(无害)页面并使用它来查看证书链。 否则,运行openssl s_client -connect $host:443 -showcerts ,一旦连接进入EOF(Unix ^ D,Windows ^ Z),然后将每个----BEGIN CERT...放到-----END CERT...阻止在另一个文件中openssl x509 -noout -subject -issuer -startdate -enddate运行openssl x509 -noout -subject -issuer -startdate -enddate

修复:如果这是问题,似乎没有任何方法可以直接关闭它,除非关闭所有证书检查(从而失去一些SSL的安全性),但添加服务器实体证书您的信任库应该工作,因为Java不会validation链。 (您不需要删除已经存在的内容,只需使用尚未使用的别名。)祝您好运。