请求开始时的异常 - ClientAuth SSL

Posted

技术标签:

【中文标题】请求开始时的异常 - ClientAuth SSL【英文标题】:Exception at start of request - ClientAuth SSL 【发布时间】:2011-06-17 03:57:57 【问题描述】:

我有一个嵌入 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。在未启用客户端身份验证的情况下,通信正常进行。使用客户端身份验证,我们总是在第一次握手时得到异常,而下一次是正确完成并继续进行而没有异常。在服务器端使用 jetty 6.1.14 版本

【问题讨论】:

正如@Dan 所说,您需要将javax.net.debug 系统属性设置为alldebug。对于大多数 java 启动器,您只需将 -Djavax.net.debug=all` 添加到参数中。 【参考方案1】:

我在 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:“no_renegotiation(100)”类型的警告Alert 消息将发送到对等方,并且连接将保持打开状态。当收到“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

【讨论】:

非常感谢。设置这些属性没有帮助。我试过调试。请查看更新后的问题。 这将是添加的方式: System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true"); System.setProperty("sun.security.ssl.allowLegacyHelloMessages", "true");【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

试过了,不管是否设置了上述两个属性,都会出现同样的错误【参考方案4】:

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

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

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

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

    点击扳手图标: 选择选项 选择“幕后”选项卡 点击更改代理设置 选择“高级”选项卡 向下滑动并检查 TLS 1.0 关闭并重新启动所有打开的浏览器。

IE:

    点击工具菜单 单击 Internet 选项 高级选项卡 滚动到安全部分 启用 TLS 1.0

火狐:

    点击工具 点击选项 高级选项卡 加密选项卡 启用 TLS 1.0

然后你还提到:

这是服务器的消息 将其证书与请求一起发送 我相信客户证书。

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

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

【讨论】:

是的,丹。所有浏览器都启用了 TLSv1 和 SSLv3。客户端证书已安装,并且在第二次握手后也可以正常工作。就像我说的;它只是给出这个例外的第一次握手。第二次;我可以选择证书并且在那里通信正常。我检查了禁用客户端身份验证并且它的工作没有任何例外。 :( 我认为您需要更具体地说明“第一次”和“第二次”的含义。你的意思是从客户端还是从服务器端表现出来的?此外,使用 javax.net.debug=all 从第一次运行和第二次运行将整个输出捕获到文件中。去掉时间戳(perl、文本编辑器宏等)。然后并排比较这两个文件并查找任何主要差异。我想知道客户端是否在失败的请求和成功的请求上提供相同的客户端证书(指纹/哈希)。 在服务器端启用了调试。当我们尝试在服务器上打开链接时;这种行为甚至在客户端证书选择窗口弹出之前就已经发生。从用户的角度来看,他们不会看到区别;但实际上他们只是在第二次握手时才建立联系。我也使用 ssltap 来捕获流量。我将尝试将来自 ssltap 的日志放在某处并链接它。据我所知,它们几乎相同。但我可能会遗漏一些东西。

以上是关于请求开始时的异常 - ClientAuth SSL的主要内容,如果未能解决你的问题,请参考以下文章

在Android Nougat中使用自签名证书通过https连接时的SSL握手异常

Android 4.x HTTPS请求SSL handshake aborted异常解决

无法建立 SSL 连接,请参阅内部异常

从 urllib.request 向 HTTPServer 发出许多并发请求时的神秘异常

Java Paypal 集成 SOAP JAX-WS - SSL 握手异常

无法建立 SSL 连接