繁体   English   中英

Java HttpsUrlConnection,连接重置

[英]Java HttpsUrlConnection, connection reset

String url1 = "foo1.blabla.com";
String url2 = "foo2_bar.blabla.com";
URLConnection urlConnection = new URL(url1).openConnection();
urlConnection.setDoInput(true);

//Fails
InputStream in = urlConnection.getInputStream();

我们能够毫无问题地连接 url1,但他们最近将 url 更改为 url2 并声称他们只更改了 url 而没有其他任何内容。 但修改后我得到以下异常:

java.net.SocketException:连接重置在 java.net.SocketInputStream.read(SocketInputStream.java:210) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.security.ssl.InputRecord.readFully(InputRecord) .java:465) at sun.security.ssl.InputRecord.read(InputRecord.java:503) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975) at sun.security.ssl.SSLSocketImpl.performInitialHandshake( SSLSocketImpl.java:1367) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379) at sun.net.www.protocol.https .HttpsClient.afterConnect(HttpsClient.java:559)

  • 我尝试了 Java 1.8.181、1.8.191。

  • 我尝试使用 customhostnameverifier 如

    类 CustomHostNameVerifier 实现 HostnameVerifier {

     public CustomHostNameVerifier() { } @Override public boolean verify(String arg0, SSLSession arg1) { return true; }

    }

  • url1 和 url2 具有相同的证书信息,我还使用 keytool 将它们的 .cer 添加到密钥库中。

  • 没有防火墙或防病毒问题,因为在同一台计算机上我可以使用邮递员连接到 url2。 我在我的 Java 代码中添加了与 postman 相同的标头。

  • 我检查了以下页面:

java.net.SocketException:使用 HTTPConnection 重置连接

是什么导致了我的 java.net.SocketException:连接重置?

java.net.SocketException:连接重置

使用有效 URL 在 HttpsUrlConnection 上重置连接

  • 我用 -Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack 运行程序

并看到以下差异:

对于 url1(工作正常)

SendHTTPTest.f9() 连接已打开 允许不安全的重新协商:false 允许旧的 hello 消息:true 是初始握手:true 是安全的重新协商:false main,SNI 中的先前服务器名称(type=host_name (0),value= foo1.blabla。 com ) 被替换为 (type=host_name (0), value= foo1.blabla.com ) Extension extended_master_secret Extension server_name, server_name: [type=host_name (0), value= foo1.blabla.com ] *** main, WRITE : TLSv1.2 Handshake, length = 226 main, READ: TLSv1.2 Handshake, length = 2303 *** ServerHello, TLSv1.2

对于 url2(连接重置问题)

SendHTTPTest.f9() 连接打开main,“foo2_bar.blabla.com”不是服务器名称指示的合法主机名允许不安全的重新协商:false 允许旧的 hello 消息:true 是初始握手:true 是安全的重新协商:false main,“foo2_bar .blabla.com”不是服务器名称指示的合法主机名,写入:TLSv1.2 握手,长度 = 193 主,处理异常:java.net.SocketException:连接重置主,发送 TLSv1.2 警报:致命,描述=unexpected_message main, WRITE: TLSv1.2 Alert, length = 2 main, 异常发送警报: java.net.SocketException: Connection reset by peer: socket write error main, called closeSocket() java.net.SocketException: Connection reset

可能该消息导致主要,“foo2_bar.blabla.com”不是用于服务器名称指示问题的合法主机名,它与 SNI 相关吗? url2 中的下划线可能会导致问题?

使用Java8的SNI客户端之谜

(来自解决意见和搜索)

许多事情可能会导致SSL/TLS 握手重置,具体取决于服务器,但现在一个常见的问题是缺少服务器名称指示 (SNI)

除了一些旧版本中的错误外, Java (JSSE) 在以下几种情况下无法发送 SNI

  • 主机名是 IP 地址(v4 或 v6)

  • 主机名不包含点,或末尾有点(即“看起来不像”DNS 名称)

  • 主机名包含除字母、数字和连字符(在 DNS 和 IDN 允许的位置)和点(在 DNS 允许的位置)之外的 ASCII 字符; 此限制显然基于 RFC952,如 STD3=RFC1123 中所述。 (非ASCII字符——Unicode U+0080 及更高版本——按照 IDN 规则转换为 punycode,它在设计上满足限制。)

在这种情况下,问题是第三点; 主机名包含一个 ASCII 下划线。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM