Java SSLHandShakeException 没有合适的协议

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38205947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:04:51  来源:igfitidea点击:

SSLHandShakeException No Appropriate Protocol

javasslbufferedreader

提问by ChrisianBartram

I recently added SSL to my website and it can be accessed over https. Now when my java application tries to make requests to my website and read from it with a buffered reader it produces this stack trace

我最近在我的网站上添加了 SSL,它可以通过 https 访问。现在,当我的 Java 应用程序尝试向我的网站发出请求并使用缓冲读取器从中读取时,它会生成此堆栈跟踪

Im not using a self signed certificate the cert is from Namecheap who uses COMODO SSL as the CA to sign my certificate. im using java 8

我没有使用自签名证书,证书来自 Namecheap,他使用 COMODO SSL 作为 CA 来签署我的证书。我正在使用 Java 8

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.Handshaker.activate(Handshaker.java:503)
at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1482)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1351)
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)

My code is very basic and simply tries to read the page on my site using a buffered reader

我的代码非常基本,只是尝试使用缓冲阅读器读取我网站上的页面

 private void populateDataList() {
    try {
        URL url = new URL("https://myURL.com/Data/Data.txt");
        URLConnection con = url.openConnection();
        con.setRequestProperty("Connection", "close");
        con.setDoInput(true);
        con.setUseCaches(false);

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String line;
        int i = 0;
        while((line = in.readLine()) != null) {
            this.url.add(i, line);
            i++;
        }
    }   catch (Exception e) {
        e.printStackTrace();
    }

}

Ive tried adding my SSL certificate to the JVM's Keystore and Ive also even tried to accept every certificate (which defeats the purpose of SSL I know) with this code

我已经尝试将我的 SSL 证书添加到 JVM 的密钥库中,我什至还尝试使用此代码接受每个证书(这违背了我所知道的 SSL 的目的)

 private void trustCertificate() {
    TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
    };
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (GeneralSecurityException e) {
    }
    try {
        URL url = new URL("https://myURL.com/index.php");
        URLConnection con = url.openConnection();
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String line;
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }

    } catch (Exception e) {

    }
}

Im stumped and any help would be much appreciated!

我很难过,任何帮助将不胜感激!

回答by automaton

protocol is disabled or cipher suites are inappropriate

The key to the problem lies in that statement. What it basically means is either:

问题的关键在于那句话。它的基本含义是:

  1. The TLS implementation used by the client does not support the cipher suites used by the server's certificate.
  2. The TLS configuration on the server has disabled cipher suites supported by the client.
  3. The TLS configurations on the client disable cipher suites offered by the server.
  4. TLS version incompatibility between the client and server.
  1. 客户端使用的 TLS 实现不支持服务器证书使用的密码套件。
  2. 服务器上的 TLS 配置已禁用客户端支持的密码套件。
  3. 客户端上的 TLS 配置禁用服务器提供的密码套件。
  4. 客户端和服务器之间的 TLS 版本不兼容。

This leads to handshake failure in TLS, and the connection fails. Check one or all of the three scenarios above.

这会导致 TLS 中的握手失败,并且连接失败。检查上述三种情况中的一种或全部。

回答by wwjih123

In $JRE/lib/security/java.security:

$JRE/lib/security/java.security

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, RC4, DES, MD5withRSA, DH keySize < 1024, \
EC keySize < 224, 3DES_EDE_CBC, anon, NULL

This line is enabled, after I commented out this line, everything is working fine. Apparently after/in jre1.8.0_181 this line is enabled.

此行已启用,在我注释掉此行后,一切正常。显然,在 jre1.8.0_181 之后/中,此行已启用。

My Java version is "1.8.0_201.

我的 Java 版本是“1.8.0_201.