Java HttpsUrlConnection,连接重置
我们能够毫无问题地连接url1,但他们最近将url更改为url2,并声称他们只更改了url,其他什么都没有更改。但在修改后,我得到了以下例外: java.net.SocketException:连接重置 位于java.net.SocketInputStream.read(SocketInputStream.java:210) 位于java.net.SocketInputStream.read(SocketInputStream.java:141) 位于sun.security.ssl.InputRecord.readfull(InputRecord.java:465) 位于sun.security.ssl.InputRecord.read(InputRecord.java:503) 位于sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975) 位于sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367) 位于sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395) 位于sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379) 位于sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)Java HttpsUrlConnection,连接重置,java,ssl,https,httpurlconnection,connection-reset,Java,Ssl,Https,Httpurlconnection,Connection Reset,我们能够毫无问题地连接url1,但他们最近将url更改为url2,并声称他们只更改了url,其他什么都没有更改。但在修改后,我得到了以下例外: java.net.SocketException:连接重置 位于java.net.SocketInputStream.read(SocketInputStream.java:210) 位于java.net.SocketInputStream.read(SocketInputStream.java:141) 位于sun.security.ssl.Input
- 我试过Java1.8.181,1.8.191
- 我尝试使用customhostnameverifier,例如
类CustomHostNameVerifier实现HostnameVerifier{
}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和url2都有相同的证书信息,我还使用keytool将它们的.cer添加到密钥库中
- 没有防火墙或防病毒问题,因为在同一台计算机上,我可以通过邮递员连接到url2。我在java代码中添加了与postman相同的标题
- 我查看了以下页面:
- 我用计算机运行程序 -Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager-Djava.security.debug=access:stack
- 主机名是一个IP地址(v4或v6)
- 主机名不包含点,或在末尾有点(即“看起来”不像DNS名称)
- 主机名包含ASCII字符,而不是字母、数字和连字符(在DNS和IDN允许的位置)和点(在DNS允许的位置);该限制显然基于STD3=RFC1123中引用的RFC952。(非ASCII字符——Unicode U+0080及以上——按照IDN规则转换为punycode,其设计满足这些限制。)
在这种情况下,问题是第三点;主机名包含ASCII下划线。我从u2中删除了域名并替换为ip地址,错误消息foo2 it not a legal hostname for server name indication消失,但问题仍然存在***main,WRITE:TLSv1.2 Handshake,length=193 main,处理异常:java.net.SocketException:Connection reset main,SEND TLSv1.2 ALERT:fatal,description=unexpected_message main,WRITE:TLSv1.2 ALERT,length=2 main,异常发送ALERT:java.net.SocketException:Connection reset by peer:socket WRITE error main,称为closeSocket()当今许多HTTPS服务器需要SNI,如果使用(包含)地址或仅包含一个标签名的URL,不是至少有一个点的DNS格式名称,Java/JSSE不发送SNI,这会导致握手失败。查看所有调试日志,它显示了这一点。(如果您的系统上有其他名称解析,如/etc/hosts或NIS或MDN,则名称实际上不必在DNS中,它必须是DNS格式。)顺便说一句,如果主机名或证书验证出现问题,它将产生非常不同的症状,决不重置连接,所以这些只是免费降低了您的安全性。Url1的格式是blabla.foo1。com和url2的格式为blabla_nteapi.foo2。com下划线会导致问题吗?或者他们在文档中称之为nte api是什么,还有一个tnt api和一个我以前从未听说过的招摇过市链接。在旧的网址我从来没有听说过他们确实可以!我读得不够远。JSSE中的代码直接禁止地址和无点(最后还有点,我没有提到,但很少使用)。然而,它随后调用
java.net.IDN
来处理“国际化”名称(即包含非ASCII gr的域名)
public CustomHostNameVerifier() {
}
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}