为什么支持TLSV1.2的url只能在android 4.4上使用证书,而不能没有证书

为什么支持TLSV1.2的url只能在android 4.4上使用证书,而不能没有证书,android,ssl,retrofit,tls1.2,Android,Ssl,Retrofit,Tls1.2,我正在从android 4.4版本设备调用api,该设备仅支持TLSV1.2,您可以查看。所以,若我在请求中添加证书,它可以正常工作,但API不需要任何证书,所以若并没有证书,它就会抛出 找不到可接受的协议异常 我已尝试使用以下代码启用TLSV1.2: ConnectionSpec requireTls12 = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) .tlsVersions(TlsVersion

我正在从android 4.4版本设备调用api,该设备仅支持TLSV1.2,您可以查看。所以,若我在请求中添加证书,它可以正常工作,但API不需要任何证书,所以若并没有证书,它就会抛出

找不到可接受的协议异常

我已尝试使用以下代码启用TLSV1.2:

ConnectionSpec requireTls12 = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                .tlsVersions(TlsVersion.TLS_1_2)
                .build();
        OkHttpClient client = new OkHttpClient.Builder()
                .connectionSpecs(Arrays.asList(requireTls12))
                .build();

        return client.newBuilder().build();
以及所有其他解决方案

我无法使用Google Play Services中的ProviderInstaller启用它,因为我的设备没有安装Google Play Services

这是具有客户端证书的工作代码:

CertificateFactory certificateFactory = null;
        Certificate certificate = null;
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        try {
            certificateFactory = CertificateFactory.getInstance("X.509");
            certificate = certificateFactory.generateCertificate(certInputStream);
            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", certificate);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);

            //Initialize Interceptors
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);

            //Assign custom trusted ssl to builder
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            builder.sslSocketFactory(sslSocketFactory);
            builder.addInterceptor(loggingInterceptor);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } 

有人能提出解决方案吗?

“如果我在请求中添加证书,它工作正常,但API不需要任何证书,因此如果没有证书,它将无法找到可接受的协议异常。”-我不确定“在请求中添加证书”是什么意思(无代码)但我想你指的是客户证书。如果它可以使用客户机证书,但不能不使用(这是唯一的更改),那么服务器显然需要客户机证书。但我建议您不仅发布失败的代码,而且发布正在运行的代码,以便弄清楚实际的区别是什么。是的,我指的是客户端证书。Api人员说Api不需要证书,我根据logsA假设TLSV1.2的SSLhandshake问题。如果服务器需要客户端证书,但客户端不提供任何证书,则会发生SSL握手问题。@Steffen在添加上述代码以启用TLSV1.2后,它会引发异常:java.net.UnknownServiceException:无法找到可接受的协议。isFallback=false您的工作代码不使用客户端证书。它只将证书设置为受信任(
ca
),尽管它稍后会覆盖验证以接受任何内容(不知道您在这里试图实现什么,可能您也不知道)。主要区别在于,工作客户机并不局限于TLS1.2,但也将执行TLS1.0及更高版本。我建议不要在客户机中限制TLS版本,因为它将在双方都使用最佳版本支持。