8

我有一个在 JBoss 下运行的用 Java 编写的 REST API。最近我们将 JVM 从 1.6 更新到了 1.7。这开始导致只有我们正在连接的 Python 客户端出现问题。间歇性地,Python 客户端会出现握手失败。我们编写了一个非常简单的测试来重现问题:

import httplib2

for i in range(1,500):
    print i
    response, content = httplib2.Http(disable_ssl_certificate_validation=True).request('https://server.com:8443',)

给出以下输出:

.
.
.
64
65
66
67
Traceback (most recent call last):
  File "api_test/test.py", line 6, in <module>
    response, content = httplib2.Http(disable_ssl_certificate_validation=True).request('https://server.com:8443/rest/solidtumor/2012/id/50d3216c092c8554b8b9f384?glossary=true&api_key=APIKEY',)
  File "/home/hostovic/api_test/httplib2/__init__.py", line 1445, in request
    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
  File "/home/hostovic/api_test/httplib2/__init__.py", line 1197, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "/home/hostovic/api_test/httplib2/__init__.py", line 1133, in _conn_request
    conn.connect()
  File "/home/hostovic/api_test/httplib2/__init__.py", line 914, in connect
    raise SSLHandshakeError(e)
httplib2.SSLHandshakeError: [Errno 1] _ssl.c:490: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

第 67 次调用在此运行中失败,但每次运行测试时它在不同的时间失败。

我们的其他客户端(Java、Groovy 和 Ruby)可以正常工作。

如果我将 JVM 切换回 1.6,故障就会停止。

我使用以下方法进行了 openssl 检查:

openssl s_client -connect server.com:8443

它返回了这个:

New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : EDH-RSA-DES-CBC3-SHA
    Session-ID: 50E748EA341BB433EEBC7386C606313C2B8B86360ED71DC8F3B0A14A1579D91B
    Session-ID-ctx:
    Master-Key: 1007AC489D60FE2D818F71A5A6873D5BBF5B1770BEC31CDBF29D0562DB0D30A33D9EBBA8AD211B8E24B23494B20A6223
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1357334762
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

这似乎是正确的,但我不确定。如果每次通话都失败,那将是一回事,但只是随机失败真的很奇怪。有人见过这个吗?

4

2 回答 2

5

使用 Python 2.6 连接到 Tomcat 7 (Java 1.7) 时,我遇到了同样的间歇性错误。

当我将 JVM 从 1.7u1 升级到 1.7u6 时,我第一次开始遇到这个问题。从这篇文章来看,Java 中的密码偏好顺序似乎发生了变化:

Java 7 无法生成 DH 密钥对

在 JVM 升级之前,SSL_RSA_WITH_3DES_EDE_CBC_SHA 是用于 SSL 通信的首选密码。升级后,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 优先。95% 的情况下,SSL 通信正常。但有 5% 的情况下,它会如您所描述的那样失败。

似乎 Python 在 Diffie-Hellman 密码方面存在问题。Python 3.3 中有一个修复:

http://bugs.python.org/issue13626

我目前的解决方法是从我在 Tomcat 中启用的密码中删除 Diffie-Hellman 密码。我还没有尝试升级到 Python 3.3。

于 2013-01-08T22:03:44.433 回答
0

从 Java 6 升级到 Java 7 后,我遇到了同样的问题。

我对此进行了一些调试,结果发现这是 Java 7 的 DHE 密码套件实现中的一个错误:大约 0.5% 的 DHE 密码套件的 SSL 握手失败。(它与 Python 无关,也可以使用“openssl”命令行工具来重现该错误。)

我已向 Oracle 报告了该错误,有关详细信息,请参阅http://mail.openjdk.java.net/pipermail/security-dev/2013-May/007435.html。同时,唯一的解决方法是禁用 DHE 密码套件(在任一端)。

于 2013-05-15T08:20:33.057 回答