sslv2和sslv3兼容性还是证书问题?

时间:2014-06-05 05:21:59

标签: java ssl https

我有一个在服务器“CCC”中运行的unix脚本,从中调用在另一台服务器“GGG”中运行的servlet。(服务器GGG是一个安全服务器,与普通服务器相比具有额外的防火墙)

此外,CCC是一个ETL服务器,它有一个JRE。该脚本使用http调用servlet,因为我应用了规则,因此重定向发生在https,端口号也在变化。

当我尝试调用servlet时出现错误的证书错误。

在普通IE或chrome中给出的servlet URL给了我一个有效的响应,能够命中服务器GGG。

我得到的错误是:

javax.net.ssl.SSLHandshakeException: bad certificate
    at com.ibm.jsse.bg.a(Unknown Source)
    at com.ibm.jsse.b.a(Unknown Source)
    at com.ibm.jsse.b.write(Unknown Source)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:139)
    at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:827)
    at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1975)
    at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)
    at com.tgt.task.client.TaskClient.doGet(TaskClient.java:153)
    at com.tgt.task.client.TaskClient.runClient(TaskClient.java:91)
    at com.tgt.task.client.TaskClient.completeTask(TaskClient.java:68)
    at com.tgt.task.client.TaskClient.main(TaskClient.java:53)

所以,最初我在cacerts中检查了CCC服务器的证书,它拥有所有的根证书,除了颁发给URL的证书。

我们发现该问题在URL的BIG IP证书续订后开始,我已经跟进我的网络团队来查看问题,他们已经确认来自服务器CCC的流量正好通过GGG通过防火墙。

因此,当我们尝试调用URL时捕获了流量,我们得到了以下内容:

client  server  SSLV2   282 Client Hello
server  client  SSLV3   1631    Server Hello
server  client  SSLv3   433 Certificate
client  server  SSLV3   190 Alert(Level: Fatal, Description: Bad Certificate)

由于客户端和服务器使用的SSL版本,您能告诉我这个问题吗?

或我在分析中遗漏的其他一些事情。

我甚至尝试将URL的证书导入服务器CCC中的cacerts,但我收到了错误:

keytool error:java.lang.Exception:输入的不是X.509证书

所以,我为URl获取了PKCS7证书,并试图将其转换为.cer并尝试导入,但得到了同样的错误。

2 个答案:

答案 0 :(得分:0)

如果它适用于浏览器,但不适用于脚本,则通常与服务器名称指示(SNI)有关。使用SNI,您可以在同一IP地址后面拥有多个具有不同证书的主机。虽然所有当前浏览器都支持SNI,但其他实现可能默认情况下不启用或不启用SNI。如果客户端无法在具有相同IP的多个证书的站点上使用SNI,则只能获得默认证书,这通常是错误的证书。

我不是您正在运行的Java版本,但我建议您确定您的版本,然后谷歌了解如何在您的版本中使用SNI。根据我的理解,SNI仅在Java版本7中启用。

答案 1 :(得分:0)

我检查了捕获的网络数据包,发现URL根据BIG IP端的SSL配置向服务器CCC提供了正确的证书,客户端CCC无法对其进行验证。并返回错误的证书消息。

这里我尝试了openssl并尝试了命令:

s_client -connect host:443
verify error:num=20:unable to get local issuer certificate
verify error:num=27:certificate not trusted
verify error:num=21:unable to verify the first certificate

`No client certificate CA names sent`
 SSL handshake has read 1745 bytes and written 304 bytes
 New, TLSv1/SSLv3, Cipher is RC4-SHA
 Server public key is 1024 bit
 Compression: NONE
 Expansion: NONE
 SSL-Session:
Start Time: 1402019174
Timeout   : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)

我猜我的服务器没有发送完整的信任链列表,因此客户端无法验证它。

我不确定我的分析是否正确,我也提到了以下帖子:

OpenSSL: unable to verify the first certificate for Experian URL

如果我需要发送我的服务器以发送完整的可信链列表,我需要更改设置?在BIG Ip结束,还是在服务器端?