SSLHandshakeException:握手失败 SSL 例程:OPENSSL_internal:WRONG_VERSION_NUMBER

时间:2021-07-23 14:06:28

标签: java android nginx ssl

一段时间后返回 Android。我刚刚购买了 EV 证书,并尝试使用 SSL/TSL 连接到我的 Web 服务。我得到:

2021-07-23 09:52:12.009 26190-26225/xx.xx.wb5000dispenser E/xx.xx.wb5000dispenser.service.DispenseServiceImpl: Error registering site
    javax.net.ssl.SSLHandshakeException: Handshake failed
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:286)
        at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:192)
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:299)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:237)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:472)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:26)
        at xx.xx.wb5000dispenser.service.DispenseServiceImpl.callPost(DispenseServiceImpl.java:72)
        at xx.xx.wb5000dispenser.service.DispenseServiceImpl.registerSite(DispenseServiceImpl.java:50)
        at xx.xx.wb5000dispenser.service.Wb5000Service$DailyRegisterThread.run(Wb5000Service.java:57)
     Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x9fa470c8: Failure in SSL library, usually a protocol error
    error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER (external/boringssl/src/ssl/tls_record.cc:242 0x9d1e6f1b:0x00000000)
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:375)
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:224)
            ... 16 more

我在此处的其中一个答案中发现我应该尝试 testssl.sh。我安装了它,这是一些报告...

...
Testing protocols via sockets except NPN+ALPN 

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      not offered
 TLS 1.1    not offered
 TLS 1.2    offered (OK)
 TLS 1.3    offered (OK): final
 NPN/SPDY   http/1.1 (advertised)
 ALPN/HTTP2 http/1.1 (offered)
...
 Rating (experimental) 

 Rating specs (not complete)  SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)
 Specification documentation  https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide
 Protocol Support (weighted)  100 (30)
 Key Exchange     (weighted)  90 (27)
 Cipher Strength  (weighted)  90 (36)
 Final Score                  93
 Overall Grade                A
 Grade cap reasons            Grade capped to A. HSTS is not offered

让我知道查看更多内容是否有用...

我查看了服务器(在 AWS 上托管的 nginx),在此期间日志中没有错误。

这里是 SSL 上下文的创建:

    try {
        sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, new java.security.SecureRandom());
    } catch (NoSuchAlgorithmException | KeyManagementException ex) {
        Log.e(TAG, "Error creating SSL context", ex);
    }

TSLv1.3 因不受支持而失败。

这是我的连接代码:

    try {
        URL url = new URL(urlName);
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
        urlConnection.setDoOutput(true);
        urlConnection.setFixedLengthStreamingMode(bytesToSend.length);

        OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); //Exception here
        out.write(bytesToSend);
        out.flush();

        InputStream in = new BufferedInputStream(urlConnection.getInputStream());
        result = readStreamAsString(in);
    }
   catch(Exception exception) {
        Log.e(TAG, "Error registering site", exception);
        throw new Square1Exception("Error hitting:" + urlName, exception);
    }

如输出流创建所示那样爆炸。

我的平板电脑运行的是 Android 9,这比我发现的大多数类似问题都要新。

感谢所有建议。

1 个答案:

答案 0 :(得分:0)

正如 Joy 和 alexrait 所建议的,问题不在于指定 SSL 上下文。显然,默认情况下,android 不会尝试最好的。 :(

所以,我在这里添加了代码:

    try {
        sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, new java.security.SecureRandom());
    } catch (NoSuchAlgorithmException | KeyManagementException ex) {
        Log.e(TAG, "Error creating SSL context", ex);
    }

然后添加这一行来使用它:

        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

现在似乎一切正常。感谢您的帮助。