SSL 连接重置

发布于 2024-10-29 01:55:54 字数 2095 浏览 7 评论 0原文

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

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 连接:

     Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        SSLSocketFactory 工厂 = (SSLSocketFactory) SSLSocketFactory.getDefault();
    
        SSLSocket套接字=(SSLSocket)factory.createSocket(“...”,443);
    
        Writer out = new OutputStreamWriter(socket.getOutputStream());
        // https 需要 GET 行中的完整 URL
        //
        out.write("GET / HTTP/1.0\r\n");
        out.write("\r\n");
        出.flush();
    
        // 读取响应
        BufferedReader = new BufferedReader(
                    新的InputStreamReader(socket.getInputStream()));
        整数c;
        while ((c = in.read()) != -1) {
            System.out.write(c);
        }
    
        关闭();
        附寄();
        套接字.close();
    

更多细节:

  • 我尝试过的每种方法都适用于其他 SSL 服务器,这是这个特定的服务器(我无权讨论什么服务器,这是一个业务)合作伙伴)
  • 我可以使用 Web 浏览器连接到该服务器,也可以使用curl 伪造 SOAP 请求;这是 Java 特有的东西。

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

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

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)

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)

I have tried:

  • 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();
    

A few more details:

  • Every method I have tried has worked against other SSL servers, it's this particular server (I am not at liberty to discuss what server, it's a business partner)
  • I can connect to this server both with a web browser, and with a faked up SOAP request with curl; This is something Java-specific.

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.

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

向日葵 2024-11-05 01:55:54

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

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

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

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

    socket.setEnabledProtocols(new String[] { "SSLv3" });
    
  • 如果您使用更高级别的库,您可能需要将所有 SSL 请求设置为仅使用 v3,即使用“https.protocols”系统属性完成:

    java -Dhttps.protocols=SSLv3
    

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.

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" });
    
  • 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
    
溺深海 2024-11-05 01:55:54

也许还可以尝试将 HTTP 版本设置为 1.1 而不是 1.0,因为新标准有一些真正的优势。

Maybe also try setting the HTTP version to 1.1 instead of 1.0, as there's some real advantages to the newer standard.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文