简体   繁体   English

Java-HTTPS GET调用从带有handhake_failure的EC2实例失败,在本地工作

[英]Java - HTTPS GET call fails from EC2 instance with handshake_failure, works locally

I'm running out of ideas, which is why I'm asking for help here. 我的想法不多了,这就是为什么我在这里寻求帮助。 I have a small class that does a REST call over HTTPS. 我有一个小类,可以通过HTTPS进行REST调用。 I'm doing some kind of scraping, and would like to avoid installing all SSL certificates if possible. 我正在进行某种形式的抓取,并尽可能避免安装所有SSL证书。

The code works well locally (both from Eclipse and a standalone Tomcat), but it fails with a javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure every time when running from my AWS EC2 instance. 该代码在本地运行良好(从Eclipse和独立的Tomcat均可),但是它失败并显示javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure每次从我的AWS EC2实例运行时,都会javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Code is: 代码是:

// apiUrl looks like https://hsreplay.net/api/v1/games/jdUbSjsEcBL5rCT7dgMXRn
private String restGetCall(String apiUrl) throws Exception {
    System.setProperty("javax.net.debug", "ALL");
    SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) {
        @Override
        protected void prepareSocket(SSLSocket socket) throws IOException {
            try {
                log.debug("************ setting socket HOST property *************");
                PropertyUtils.setProperty(socket, "host", "hsreplay.net");
                socket.setEnabledProtocols(new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" });
            }
            catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
                log.error(ex.getMessage());
                slackNotifier.notifyError(ex);
            }
            super.prepareSocket(socket);
        }

    };
    CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

    HttpGet httpGet = new HttpGet(apiUrl);
    CloseableHttpResponse response1 = httpClient.execute(httpGet);
    StringBuilder result = new StringBuilder();
    try {
        System.out.println(response1.getStatusLine());
        HttpEntity entity1 = response1.getEntity();
        BufferedReader rd = new BufferedReader(new InputStreamReader(entity1.getContent()));
        String line;
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        // do something useful with the response body
        // and ensure it is fully consumed
        EntityUtils.consume(entity1);
    }
    finally {
        response1.close();
    }
}

I also tried the basic version (without any override of the SSLFactory methods), but to no avail. 我也尝试了基本版本(没有对SSLFactory方法的任何覆盖),但无济于事。

Also, I don't manage to get the logs from javax.net.debug on Tomcat (neither on the remote nor on a local one), so if you have any idea here that could also be very useful. 另外,我也无法从Tomcat上的javax.net.debug (无论是在远程还是本地)上获取日志,因此,如果您在这里有任何想法,那也可能非常有用。

Please let me know if I can provide more information, and thanks a lot for your help! 如果可以提供更多信息,请告诉我,非常感谢您的帮助!

Sébastien 塞巴斯蒂安

Handshake failures might be caused by lots of different reasons, like the wrong Java version, server settings, setting a hostname verifier (bad idea anyway), SNI ... . 握手失败可能是由许多不同的原因引起的,例如错误的Java版本,服务器设置,设置主机名验证程序(无论如何都是不好的主意),SNI...。 The current information in this question are not enough to say for sure what the problem is. 该问题中的当前信息不足以确定问题是什么。

When looking at the SSLLabs report for the server two information look interesting: 查看服务器的SSLLabs报告时 ,两个信息看起来很有趣:

  • The server needs SNI. 服务器需要SNI。
  • The server supports only ECDHE ciphers. 服务器仅支持ECDHE密码。

The first might be a problem with older Java versions or even with JDK8 if you set a hostname verifier (which you do although it would not be necessary for this site). 第一个可能是旧Java版本甚至JDK8的问题,如果您设置了主机名验证程序(您可以这样做,尽管此站点不需要这样做)。

The second might be a problem with older Java version or if the cryptography extensions for unlimited strength are not installed. 第二个可能是较旧的Java版本存在问题,或者未安装无限强度的加密扩展。

@SteffenUlrich's answer put me on the correct rails. @SteffenUlrich的回答使我处于正确的轨道上。 The issue was indeed because of the ECDHE ciphers that aren't supported in open jdk 7. I migrated to Oracle's JDK 8, and things are working fine now. 问题的确确实是由于开放jdk 7不支持ECDHE密码。我迁移到Oracle的JDK 8,现在一切正常。

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

相关问题 从EC2实例上的Maven提取依赖项时获取handhake_failure - Getting handshake_failure when pulling dependencies from Maven on EC2 Instance 从tomcat服务器进行https调用时的Tomcat handshake_failure - Tomcat handshake_failure when https call from the tomcat server Java https客户端在JDK 1.5中抛出“收到的致命警报:握手失败”,但在JDK1.6上有效 - java https client throws “Received fatal alert: handshake_failure” with JDK 1.5 but works on JDK1.6 Java SSL handshake_failure - Java SSL handshake_failure RestTemplate GET Request 中的 handshake_failure 在浏览器中工作 - handshake_failure in RestTemplate GET Request which works in browser Java 升级 8.0.6.15 到 8.0.6.25 握手失败后,但在将旧安全文件夹从 8.0.6.15 替换为新 java 版本 8.0.6.25 后工作 - After Java Upgrade 8.0.6.15 to 8.0.6.25 handshake_failure, but works after replace old security folder from 8.0.6.15 to new java version 8.0.6.25 Java 1.6 TLS 1.2 handshake_failure - Java 1.6 TLS 1.2 handshake_failure Java SSL SSLHandshakeException handshake_failure - Java SSL SSLHandshakeException handshake_failure java ssl handshake_failure问题 - java ssl handshake_failure issue 使用java / netty得到handshake_failure,但是对于相同的https url成功使用curl - Got handshake_failure using java/netty, but succeeded with curl for the same https url
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM