10

我有一个嵌入 Jetty 的应用程序。我想在 SSL 中使用客户端证书身份验证以及启用该身份验证时;我在请求开始时收到以下异常。但是在那之后请求得到了正确的处理。此异常仅在从 IE 或 Chrome 访问时出现。从 Firefox 访问时它不会出现。我们有自定义 SSLConnector 扩展 SslSocketConnector。我正在尝试调试它;但想知道是否有任何特定的地方/代码可以开始检查。

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake 
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:808) 
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112) 
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139) 
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123) 
        at org.mortbay.jetty.security.SslSocketConnector$SslConnection.run(SslSocketConnector.java:631) 
        at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:451) 
Caused by: java.io.EOFException: SSL peer shut down incorrectly 
        at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333) 
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789) 

更新:

我启用了 SSL 调试选项,并在 ServerHelloDone 消息之后立即读取此异常。这是服务器发送其证书以及我相信的客户端证书请求的消息。我不确定第一次阅读时发生了什么。任何帮助都深表感谢。

*** ClientHello, TLSv1
****
%% Created:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
*** ServerHello, TLSv1
*** Certificate chain
***
*** CertificateRequest
Cert Types: RSA, DSS
Cert Authorities:
*** ServerHelloDone
WRITE: TLSv1 Handshake, length = 703
received EOFException: error
handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

更新: 将 JDK 更新到最新版本 23 并尝试启用/禁用这两个属性。仍然得到相同的行为。

更多信息: 所有浏览器都启用了 TLSv1 和 SSLv3。在未启用客户端身份验证的情况下,通信正常进行。使用客户端身份验证,我们总是在第一次握手时得到异常,下一次是正确完成并继续进行而没有异常。在服务器端使用码头版本 6.1.14

4

4 回答 4

8

我在 TLS/SSLv3 协商中看到过类似的问题。 http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html

在 SSL/TLS 中,任何一方都可以发起重新协商。与第 1 阶段修复一样,在互操作模式下与未升级对等方通信并尝试启动重新协商(通过SSLSocket.startHandshake()SSLEngine.beginHandshake())的应用程序将收到SSLHandshakeException( IOException) 并且连接将被关闭 ( handshake_failure)。从未升级的对等方接收到重新协商请求的应用程序将根据现有的连接类型做出响应:

  • TLSv1:Alert“(100)”类型的警告消息no_renegotiation将发送到对等方,连接将保持打开状态。no_renegotiation当收到“”警报时,旧版本的 SunJSSE 将关闭连接。
  • SSLv3:应用程序将收到一个SSLHandshakeException,并且连接将被关闭(handshake_failure)。(“ no_renegotiation”未在 SSLv3 规范中定义。)

要设置这些模式,需要使用两个系统属性:

  • sun.security.ssl.allowUnsafeRenegotiation- 在第 1 阶段引入,这控制是否允许遗留(不安全)重新谈判。
  • sun.security.ssl.allowLegacyHelloMessages- 在第 2 阶段引入,这允许对等方进行握手而不需要正确的 RFC 5746 消息。

如果这仍然没有帮助,您可以尝试打开 SSL dedug,并查看握手。
-Djavax.net.debug=all

于 2011-01-28T11:52:41.387 回答
3

当我不小心将非 ssl 端口放在 URL 中但使用 https 启动 URL 时,我得到了这个。多哈。

有时最简单的解决方案是我们忘记的!

于 2012-08-25T12:49:41.290 回答
1

试试最新的jdk。他们修复了一个 ssl 握手错误。http://www.java.net/blogs/kumarjayanti/

于 2011-02-02T05:51:27.530 回答
1

我仍然认为这是一个 TLS/SSL 协商问题。

提交调试信息后,它表明您正在执行 TLSv1 握手。

您确定您的浏览器中启用了 TLSv1 吗?

Chrome:为了在 chrome 中启用 TLS 1.0,请执行以下操作:

  1. 点击扳手图标:
  2. 选择选项
  3. 选择“引擎盖下”选项卡
  4. 单击更改代理设置
  5. 选择“高级”选项卡
  6. 向下滑动并检查 TLS 1.0
  7. 关闭并重新启动所有打开的浏览器。

IE:

  1. 单击工具菜单
  2. 单击 Internet 选项
  3. 高级选项卡
  4. 滚动到安全部分
  5. 启用 TLS 1.0

火狐:

  1. 单击工具
  2. 单击选项
  3. 高级选项卡
  4. 加密选项卡
  5. 启用 TLS 1.0

然后您还提到:

这是服务器发送其证书以及我相信的客户端证书请求的消息。

您是否已将客户端证书安装到您正在测试的每个 Web 浏览器中?

确保您可以在没有相互/客户端身份验证的情况下首先使一切正常工作,然后一旦工作正常,将其重新添加。

于 2011-02-05T19:09:23.860 回答