javax.net.ssl.SSLHandshakeException:在 Android 7.0 中握手失败

Posted

技术标签:

【中文标题】javax.net.ssl.SSLHandshakeException:在 Android 7.0 中握手失败【英文标题】:javax.net.ssl.SSLHandshakeException: Handshake failed in Android 7.0 【发布时间】:2017-09-20 17:12:44 【问题描述】:

我正在调用 API 登录,但在 android 7.0 中出现 ssl 握手错误,除此版本外,一切正常。我正在使用改造。 以下是错误。

SSL 握手终止:ssl=0xcbcd0340:SSL 库失败,通常是协议错误 错误:1000043e:SSL 例程:OPENSSL_internal:TLSV1_ALERT_INAPPROPRIATE_FALLBACK (external/boringssl/src/ssl/s3_pkt.c:610 0xebc87640:0x00000001)

也有人说添加以下代码以便解决此问题但仍然没有运气,

    ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                .tlsVersions(TlsVersion.TLS_1_2)
                .cipherSuites(
                        CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                        CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                        CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
                .build();
okHttpClient.connectionSpecs(Collections.singletonList(spec));

我什至试图放弃信任每一个证书,但仍然没有运气。以下是代码。

    public static OkHttpClient.Builder sslSocketFactory(OkHttpClient.Builder okHttpClient)

    

        try 
//             Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]
                    new X509TrustManager() 
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException 
                        

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException 
                        

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() 
                            return new java.security.cert.X509Certificate[];
                        
                    
            ;
            ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_0)
                    .allEnabledCipherSuites()
                    .build();
            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

////////            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            okHttpClient.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            okHttpClient.hostnameVerifier(new HostnameVerifier() 
                @Override
                public boolean verify(String hostname, SSLSession session) 
                    return true;
                
            );
            return okHttpClient;
         catch (Exception e) 
            throw new RuntimeException(e);
        
    

以下是我使用 android 7.0 测试的 ssllabs

ssllabs test 在所有其他 android 版本中,所有 API 都工作正常,我确实得到了响应,但我无法在 7.0 版中得到响应。

【问题讨论】:

我在 7.0 和其他操作系统中上传文件时遇到同样的错误上传成功... @PankajTalaviya 你运气好吗? @Mehdi 你找到解决方案了吗? 【参考方案1】:

其实更有可能是ssl_ciphers服务器端设置问题。

假设使用 nginx,请将您的 ssl_ciphers 设置更改为 openHab 推荐的设置:

ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;

别忘了重新加载 (systemctl reload nginx),现在所有有问题的 android 设备都应该可以正常工作了。

【讨论】:

以上是关于javax.net.ssl.SSLHandshakeException:在 Android 7.0 中握手失败的主要内容,如果未能解决你的问题,请参考以下文章