Java - 收到致命警报 : handshake_failure

标签 java handshake sslhandshakeexception

我正在尝试获取网站的 HTML 源代码。

我的代码:

public static void main(String[] args) {
    URL url;
    InputStream is;
    try {
        url = new URL("https://www.trackobot.com/");
        is = url.openStream();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但是,当运行此代码时,我得到一个异常:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
   at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
   at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
   at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
   at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
   at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
   at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
   at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
   at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
   at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
   at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546)
   at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
   at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
   at java.net.URL.openStream(URL.java:1045)
   at JsoupTutorial.ConnectToUrl.main(ConnectToUrl.java:24)

如果我更改网站,即使使用像 PayPal 这样的 https 网站,它也能正常工作。但是,我仍然有一些网站无法正常工作并抛出该异常。示例中的该网站是无法运行的网站之一。

我搜索了一下,了解到我需要将该站点的证书导入到Java keystore 中。 我说得对吗?

我的问题是 Chrome 如何设法进入那些“安全”网站并获取 HTML 代码?必须有人将证书更新(导入)到 Chrome Cer 数据库。谁执行此操作以及何时执行? (以防万一我上面的说法是正确的)。

无论如何,我想设法完美地加载这些网站并接收我想要的数据。哪里可以从基础开始学习?

谢谢。

最佳答案

这里的问题几乎可以肯定是您正在尝试访问使用 SSL/HTTPS 的网站,但您没有使用支持该功能的 API。您可以尝试将 HttpsURLConnection 与接受所有内容的(不良)信任存储一起使用。 永远不要在生产中这样做

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);

URL url = new URL("https://www.trackobot.com/");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setHostnameVerifier(new HostnameVerifier() {
    @Override
    public boolean verify(String arg0, SSLSession arg1) {
        return true;
    }
});
con.setRequestMethod("GET");
System.out.println("Response Code : " + con.getResponseCode());

BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
StringBuffer response = new StringBuffer();

while ((line = in.readLine()) != null) {
    response.append(line);
}
in.close();

System.out.println(response.toString());

private static class DefaultTrustManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}
理想情况下,假设域提供来自相对标准提供商的证书,开箱即用的 HttpsURLConnection 应该可以正常工作。由于它不适用于您的域,因此我们可以将其配置为信任所有内容。生产情况不佳,但也许可以让您暂时继续。

关于Java - 收到致命警报 : handshake_failure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51521154/

相关文章:

ssh - 批量获取SSH握手过程中的数据包

java - 如何在 Spring boot 中手动配置 SSL 握手

java - 如何使用for循环连续图像 slider ?

java - Maven Surefire 2.13 无法在 Windows 上 fork

javascript - 客户端无法获取握手错误消息

ssl - Golang : http2 and TLS handshake errors

java - 将 "jsse.enableSNIExtension"设置为 false 的安全后果是什么?

java - Swing 形式被卡住

java - 如何将检索到的数据从 firebase 保存到 android 中的字符串变量?

java - 谷歌云平台(应用引擎)SSL 握手错误