禁用了HttpsURLConnection的证书验证,仍然得到javax.net.ssl.SSLHandshakeExc



我正在编写一些将HTTP GET/POST请求发送到目标服务器的代码。当应用程序试图建立到安全服务器(https)的连接时,问题就出现了。为此,我使用了HttpsURLConnection,如下:

url = new URL("https://www.sendspace.com/");
String input, htmlResponse = "";
HttpsURLConnection con;
con = (HttpsURLConnection)url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
while ((input = br.readLine()) != null){
    htmlResponse += input;
}
br.close();

显示如下错误:

javax.net.ssl.SSLHandshakeException: Received fatal alert:handshake_failure

因此,我将上面的代码更改为:
url = new URL("https://www.sendspace.com/");
String input, htmlResponse = "";
SSLUtilities.trustAllHostnames();
SSLUtilities.trustAllHttpsCertificates();
HttpsURLConnection con;
// code below has not been changed

使用SSLUtilities.java。然而,我注意到这样做没有任何效果,因为我仍然收到完全相同的错误,再次:

javax.net.ssl.SSLHandshakeException: Received fatal alert:handshake_failure

同样,我也尝试使用不同的方法,其中涉及在启动HttpsURLConnection之前使用这一行来使用SSLCertificateValidation.java:

SSLCertificateValidation.disable();

,即使使用它也会返回与前面解释的完全相同的错误。我想确切地知道为什么这种方法不工作,我怎么可能得到规避这个错误?

请注意以下内容:

  1. 不用说,我已经在这个问题上进行了广泛的搜索,并且已经花费了相当多的时间,尝试了不同的建议和代码示例,但无济于事。我知道这个错误已经出现了很多问题,但我没能找到一个具体的答案,已经存在与我自己的。

  2. 我知道并理解由于禁用证书验证而产生的安全问题。但是,由于此应用程序将连接到100到200个不同的服务器(根据需要),因此在每个服务器的基础上管理证书是不可实现的。因此,除非有人能够说明(a)检索,(b)存储和(c)在每个服务器的基础上(在运行时)使用正确的证书的方法,所有这些都必须以编程方式完成,而不需要任何手动工作,建议"干净"的方式来完成它并不是这种情况的解决方案。

谢谢。

握手失败不是证书验证错误,因此您不能通过忽略证书错误来修复它(无论如何,这是一个坏主意)。SSLLabs页面更清楚地说明了问题的真正原因:

Java 8u31   Protocol or cipher suite mismatch   

如果您查看服务器支持的密码(同样在SSLLabs报告中),您可以看到所有密码都包含密钥大小为256的AES。但是在关于支持的密钥大小的文档中指出,由于导出限制,AES支持的最大密钥大小是128。这意味着您的客户端只提供AES128密码,而服务器只接受AES256密码,也就是说没有共享密码。

要解决此问题,您必须按照参考文档中的描述进行操作:

如果需要使用更强的算法(例如256位密钥的AES),则需要获取JCE无限制强度管辖策略文件,并安装在JDK/JRE中。

相关内容

最新更新