SSL 连接重置 [英] SSL Connection Reset

查看:39
本文介绍了SSL 连接重置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试连接到 Java 中的 HTTPS 端点.我尝试过的每种方法(更多详细信息见下文)最终都会生成此堆栈跟踪:

I am attempting to connect to an HTTPS endpoint in Java. Every method I have tried (more details below) ends up generating this stack trace:

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:753)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)

我试过了:

  • 连接 javax SOAP 库和新 URL("https://...")
  • 正在连接新 URL("https://...").openConnection()
  • 手动创建 SSL 连接:

  • Connecting with the javax SOAP libs and a new URL("https://...")
  • Connecting with new URL("https://...").openConnection()
  • Creating an SSL connection by hand:

        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();

    SSLSocket socket = (SSLSocket) factory.createSocket("...", 443);

    Writer out = new OutputStreamWriter(socket.getOutputStream());
    // https requires the full URL in the GET line
    //
    out.write("GET / HTTP/1.0\r\n");
    out.write("\r\n");
    out.flush();

    // read response
    BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
    int c;
    while ((c = in.read()) != -1) {
        System.out.write(c);
    }

    out.close();
    in.close();
    socket.close();

更多细节:

  • 我尝试过的每种方法都适用于其他 SSL 服务器,就是这个特定的服务器(我不能随意讨论是什么服务器,它是业务合作伙伴)
  • 我可以使用 Web 浏览器和使用 curl 伪造的 SOAP 请求连接到该服务器;这是 Java 特有的.

因此,很明显 Java 和 HTTPS 服务器之间在握手应该如何进行方面存在一些分歧,这可能意味着服务器有一些奇怪的 SSL 配置.但是,我无法直接访问服务器,而且访问服务器的人在地球的另一端,因此由于时区差异很大,沟通有点紧张.

So, it seems pretty clear that there is some disagreement between Java and the HTTPS server over how the handshake should go down, which probably means the server has some strange SSL configuration. However, I don't have direct access to the server, and the people who do are halfway around the world, so communication is a little strained due to very different timezones.

如果我的假设是正确的,那么可能存在哪些 SSL 问题?什么可能导致这样的事情?我在哪里可以请控制服务器的人查找问题?当我使用 curl 执行请求时,我会返回这些服务器配置标头:

If my assumptions there are correct, what possible SSL problems could there be? What might cause something like this? Where can I ask the people in control of the server to look for issues? When I do the request with curl, I get back these server configuration headers:

Server: Apache/2.2.9 (Debian) mod_jk/1.2.26 PHP/5.2.6-1+lenny10 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0
X-Powered-By: PHP/5.2.6-1+lenny10
X-SOAP-Server: NuSOAP/0.7.3 (1.114)

推荐答案

SSL 版本问题.服务器仅支持 SSLv3,Java 将从 v2 开始,并尝试向上协商,但并非所有服务器都支持该类型的协商.

It is an SSL version problem. The server only supports SSLv3, and Java will start at v2, and attempt to negotiate upwards, but not all servers support that type of negotiation.

强制 java 仅使用 SSLv3 是我所知道的唯一解决方案.

Forcing java to use SSLv3 only is the only solution I'm aware of.

编辑,我知道有两种方法可以做到这一点:

Edit, there are two ways to do this that I'm aware of:

  • 如果您是手动创建套接字,则可以设置启用的协议

  • If you are creating the socket by hand, you can set the enabled protocols

socket.setEnabledProtocols(new String[] { "SSLv3" });

  • 如果您使用的是更高级别的库,您可能需要将所有 SSL 请求设置为仅使用 v3,这是通过 "https.protocols" 系统属性实现的:>

  • If you are using a higher level library, you probably need to set all SSL requests to use v3 only, which is accomplished with the "https.protocols" system property:

    java -Dhttps.protocols=SSLv3
    

  • 这篇关于SSL 连接重置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆