Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/186.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Android OkHttpClient重用和缓存SSL连接_Android_Session_Ssl_Okhttp_Retrofit2 - Fatal编程技术网

使用Android OkHttpClient重用和缓存SSL连接

使用Android OkHttpClient重用和缓存SSL连接,android,session,ssl,okhttp,retrofit2,Android,Session,Ssl,Okhttp,Retrofit2,我使用改型和OkHttp来执行所有网络操作,比如HTTP和HTTPS url的GET、POST。一切正常,但我需要重用会话,以减少每次服务调用的握手计时过程。到目前为止,服务器为所有服务调用启动客户端和服务器之间的握手需要800毫秒以上的时间 我需要什么: Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseURL) .a

我使用改型和OkHttp来执行所有网络操作,比如HTTP和HTTPS url的GET、POST。一切正常,但我需要重用会话,以减少每次服务调用的握手计时过程。到目前为止,服务器为所有服务调用启动客户端和服务器之间的握手需要800毫秒以上的时间

我需要什么:

  Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(baseURL)
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(getOkHttpClient(context, new OkHttpClient(), context.getResources().openRawResource(R.raw.mysslcertificate)))
                            .build();

    retrofit.create(apiClass);


    public static OkHttpClient getOkHttpClient(Context context,OkHttpClient client, InputStream inputStream) {

        try {
            if (inputStream != null) {
                SSLContext sslContext = sslContextForTrustedCertificates(inputStream);


                if (sslContext != null) {
                   client = client.newBuilder()
                                        .sslSocketFactory(sslContext.getSocketFactory()).build();


                    else {

                        CLog.i(Constants.LOG_TAG_HTTPLIBRARY,"GZip not done because it is not a Analytics data");

                        client = client.newBuilder()
                                .sslSocketFactory(sslContext.getSocketFactory()).build();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return client;
    }


     private static SSLContext sslContextForTrustedCertificates(InputStream in) {
        try {
            CertificateFactory e = CertificateFactory.getInstance("X.509");
            Collection certificates = e.generateCertificates(in);
            if (certificates.isEmpty()) {
                throw new IllegalArgumentException("expected non-empty set of trusted certificates");
            } else {
                char[] password = "password".toCharArray();
                KeyStore keyStore = newEmptyKeyStore(password);
                int index = 0;
                Iterator keyManagerFactory = certificates.iterator();
                while (keyManagerFactory.hasNext()) {
                    Certificate trustManagerFactory = (Certificate) keyManagerFactory.next();
                    String sslContext = Integer.toString(index++);
                    keyStore.setCertificateEntry(sslContext, trustManagerFactory);
                }



                KeyManagerFactory var10 = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                var10.init(keyStore, password);
                TrustManagerFactory var11 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                var11.init(keyStore);
                SSLContext var12 = SSLContext.getInstance("TLS");
                var12.init(var10.getKeyManagers(), var11.getTrustManagers(), new SecureRandom());

                return var12;
            }
        } catch (Exception var9) {
            var9.printStackTrace();
        }
        return null;
    }
我必须重复使用SSLSession,以便使握手仅在第一次或特定的时间间隔内发生

我正在使用Okhttp和改型为SSL使用的代码:

  Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(baseURL)
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(getOkHttpClient(context, new OkHttpClient(), context.getResources().openRawResource(R.raw.mysslcertificate)))
                            .build();

    retrofit.create(apiClass);


    public static OkHttpClient getOkHttpClient(Context context,OkHttpClient client, InputStream inputStream) {

        try {
            if (inputStream != null) {
                SSLContext sslContext = sslContextForTrustedCertificates(inputStream);


                if (sslContext != null) {
                   client = client.newBuilder()
                                        .sslSocketFactory(sslContext.getSocketFactory()).build();


                    else {

                        CLog.i(Constants.LOG_TAG_HTTPLIBRARY,"GZip not done because it is not a Analytics data");

                        client = client.newBuilder()
                                .sslSocketFactory(sslContext.getSocketFactory()).build();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return client;
    }


     private static SSLContext sslContextForTrustedCertificates(InputStream in) {
        try {
            CertificateFactory e = CertificateFactory.getInstance("X.509");
            Collection certificates = e.generateCertificates(in);
            if (certificates.isEmpty()) {
                throw new IllegalArgumentException("expected non-empty set of trusted certificates");
            } else {
                char[] password = "password".toCharArray();
                KeyStore keyStore = newEmptyKeyStore(password);
                int index = 0;
                Iterator keyManagerFactory = certificates.iterator();
                while (keyManagerFactory.hasNext()) {
                    Certificate trustManagerFactory = (Certificate) keyManagerFactory.next();
                    String sslContext = Integer.toString(index++);
                    keyStore.setCertificateEntry(sslContext, trustManagerFactory);
                }



                KeyManagerFactory var10 = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                var10.init(keyStore, password);
                TrustManagerFactory var11 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                var11.init(keyStore);
                SSLContext var12 = SSLContext.getInstance("TLS");
                var12.init(var10.getKeyManagers(), var11.getTrustManagers(), new SecureRandom());

                return var12;
            }
        } catch (Exception var9) {
            var9.printStackTrace();
        }
        return null;
    }
我尝试过的:

  Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(baseURL)
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(getOkHttpClient(context, new OkHttpClient(), context.getResources().openRawResource(R.raw.mysslcertificate)))
                            .build();

    retrofit.create(apiClass);


    public static OkHttpClient getOkHttpClient(Context context,OkHttpClient client, InputStream inputStream) {

        try {
            if (inputStream != null) {
                SSLContext sslContext = sslContextForTrustedCertificates(inputStream);


                if (sslContext != null) {
                   client = client.newBuilder()
                                        .sslSocketFactory(sslContext.getSocketFactory()).build();


                    else {

                        CLog.i(Constants.LOG_TAG_HTTPLIBRARY,"GZip not done because it is not a Analytics data");

                        client = client.newBuilder()
                                .sslSocketFactory(sslContext.getSocketFactory()).build();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return client;
    }


     private static SSLContext sslContextForTrustedCertificates(InputStream in) {
        try {
            CertificateFactory e = CertificateFactory.getInstance("X.509");
            Collection certificates = e.generateCertificates(in);
            if (certificates.isEmpty()) {
                throw new IllegalArgumentException("expected non-empty set of trusted certificates");
            } else {
                char[] password = "password".toCharArray();
                KeyStore keyStore = newEmptyKeyStore(password);
                int index = 0;
                Iterator keyManagerFactory = certificates.iterator();
                while (keyManagerFactory.hasNext()) {
                    Certificate trustManagerFactory = (Certificate) keyManagerFactory.next();
                    String sslContext = Integer.toString(index++);
                    keyStore.setCertificateEntry(sslContext, trustManagerFactory);
                }



                KeyManagerFactory var10 = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                var10.init(keyStore, password);
                TrustManagerFactory var11 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                var11.init(keyStore);
                SSLContext var12 = SSLContext.getInstance("TLS");
                var12.init(var10.getKeyManagers(), var11.getTrustManagers(), new SecureRandom());

                return var12;
            }
        } catch (Exception var9) {
            var9.printStackTrace();
        }
        return null;
    }
因为我找不到与OkHttpClient相关的任何内容,但我尝试引用了一些解决方案,如以下链接:


但坦率地说,没有什么对我有帮助,我甚至找不到任何相关的解决方案来满足我的需求。最后,我完全被这个解决方案困扰了两周。请通过您的任何提示和建议帮助我完成任务。任何一段代码或方法对我都非常有用。提前感谢。

OkHttp支持SPDY和HTTP/2,它们为SSL提供了持续支持。您的服务器应配置为支持其中一种,在这种情况下,您的SSL会话重用将自动发生。@commonware感谢您的回复。对于SPDY和HTTP/2支持,我是否需要从服务器端实现任何东西?。如果我的服务器不支持SPDY和HTTP/2,请帮助我重新使用会话。这对我很有帮助。谢谢。“我是否需要从服务器端实现任何东西”——这是服务器配置的问题。请尝试解决这些问题。“如果我的服务器不支持SPDY和HTTP/2,如果您能帮助我重新使用会话,那将非常有帮助。”——我非常怀疑这是否可能。@Chandru即使没有SPDY或HTTP/2,您也可以缓存SSL会话,但这与OkHTTP/Android没有什么关系。您必须在服务器中配置它(如果它支持),或者找到另一个支持ssl会话缓存的web服务器。请确保它正在使用。如果是这样的话,那么在安卓方面确实会有问题