Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
例外情况;收到致命警报:握手“失败”;通过java代码发送请求时_Java - Fatal编程技术网

例外情况;收到致命警报:握手“失败”;通过java代码发送请求时

例外情况;收到致命警报:握手“失败”;通过java代码发送请求时,java,Java,注意:同一个url在浏览器中成功运行,但在java程序中无法使用同一个url。 Java代码: String urlString= "https://<host>:<port>/TestProject"; URL url = new URL(urlString); HttpsURLConnection con = (HttpsURLConnection)url.openConnection(); InputStream ins = con.getInputStream()

注意:同一个url在浏览器中成功运行,但在java程序中无法使用同一个url。 Java代码:

String urlString= "https://<host>:<port>/TestProject";
URL url = new URL(urlString);
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
InputStream ins = con.getInputStream();
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader in = new BufferedReader(isr);
String inputLine;
while ((inputLine = in.readLine()) != null)     System.out.println(inputLine);
in.close();
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
请尽早给出解决方案。请给出获得此场景的可能性,如果您知道,它将对我非常有用

最后我得到了解决方案:

String urlString= "https://<host>:<port>/TestProject";
URL url = new URL(urlString);
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
InputStream ins = con.getInputStream();
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader in = new BufferedReader(isr);
String inputLine;
while ((inputLine = in.readLine()) != null)     System.out.println(inputLine);
in.close();
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)

请首先查看:

服务器可能记录了有关该问题的更详细信息,从而可以确定和修复实际问题。但既然你想要一个早期的“可能的”答案,而不是一个准确的答案,我看到的原因是:

版本太旧:服务器需要比Java客户端提供的协议更新的协议。您似乎正在运行Java6,它最多只能实现TLSv1.0。如果服务器的要求更高,那么握手就会失败,尽管要求1.0以上目前有点争议(在未来几年内可能会被接受和普遍)解决方案:使用Java8(在其默认配置中),或至少使用Java7,并覆盖其默认配置,该配置仅为客户端提供最高TLSv1.0

版本太新:TLS规范(all)要求服务器协商更新的版本或其他更具能力的客户端,直至服务器功能,但有些服务器显然存在错误,反而未能通过握手。(浏览器/客户端通常通过退回到较旧的协议来处理这一问题,这导致了最近的“POODLE”攻击。请参阅示例和。)但是,Java6客户端不太可能触发这样的问题,如果最近的浏览器,尤其是最近的几个浏览器可以连接,这是非常不可能的。但是如果这是问题的解决方案:使用旧的Java(较差),或者配置为使用旧的协议版本,可能使用很少的(er)密码

扩展:类似地,有缺陷的服务器可能无法跳过规范所说的未实现的扩展。同样,如果现代浏览器可以连接,这是非常不可能的。但是如果这样做了,您就无法控制Java使用的扩展,因此解决方案:无。(Java中至少没有。您可以使用外部适配器,如stunnel,或应用程序级代理或中继。)

无共享密码:服务器不支持您的客户端提供的任何密码套件这不太可能,除非您的JRE/JVM配置不正确。Java实现了几乎所有已定义的密码套件,并且默认情况下启用了所有不太安全的密码套件,除了Java6仅在安装了ECC加密提供程序(默认情况下并非如此)的情况下启用椭圆曲线加密套件。服务器管理员可能合理地希望并更喜欢EC,但今天要求它是不明智的如果问题是ECC解决方案:
使用Java7或8,或向Java6添加EC提供程序如果您的JRE/JVM配置不正确使用不安全的密码套件,服务器不应同意解决方案:不要这样做

SNI:如果服务器需要服务器名称指示(目前虚拟主机通常需要的扩展),则可能会导致握手失败,但您的客户端没有提供正确的值。但是,Java6URLConnection(https)会自动从URL派生SNI,这与浏览器的做法相同,因此,如果同一URL在最近的浏览器中工作,这不是问题所在

客户端身份验证:服务器可能需要使用证书进行客户端身份验证,通常缩写为“需要(a)客户端证书”,如果客户端未提供证书,或者证书不正确,服务器可能会失败。您的浏览器可能会被配置为自动提供正确的证书和密钥,但如果您使用多个不共享密钥库的浏览器(例如Windows上的IE和Chrome),则不太可能解决方案:配置JVM/JRE(或为有限范围定制的SSLSocketFactory)以使用包含正确privateKeyEntry(密钥和证书或链)的密钥库,或者如果已配置密钥库,则将正确的privateKeyEntry放入该密钥库