私有云如何配置自签名证书?在 Android 9.0 及之后版本发生 SSL handshake timed out 异常怎么解决?

描述

本文档仅适用于私有云,且需要使用自签证书(自签名证书)绕过自签名配置的客户。

Android 9.0 及之后版本,融云 SDK 开始建立网络连接时发生 SSL handshake timed out 异常。

分析(根因分析、需求分析)

Android 9.0 开始,默认不允许明文传输,所以在建立网络连接时会使用 https 连接,同时进行安全认证。如果私有云客户未在应用内正确配置 SSL 安全认证,即会发生 SSL handshake timed out 异常。

公有云用户因为 SDK 直接使用融云内置的安全证书,一般不会遇到该问题。

解决方案

推荐使用方案一。

方案一:配置 HTTPS 使用自签证书

如果在应用里没有声明允许明文传输,那么 SDK 默认在 Android 9.0 系统上会使用 https 连接方式,也就意味着会进行安全认证。

如果 IM SDK 版本 ≧ 2.10.6.3,请在 SDK 初始化(init)之前, 调用如下方法:

注意:不要对这个方法进行进程限制, 不能只在主进程执行。因为 SDK 的业务都是在 IPC 进程操作, 所以网络操作也是在 IPC 进程。

private void setSSL() {
        SSLContext mySSLContext = getSslContext();
        if (mySSLContext != null) {
            // 设置 SDK 内部的上传下载支持自签证书
            SSLUtils.setSSLContext(mySSLContext);
            // 并且把 Glide 设置成支持自签证书(glide 内部是 HttpsURLConnection)
            // SDK 内置的图片预览用的是 Glide
            HttpsURLConnection.setDefaultSSLSocketFactory(mySSLContext.getSocketFactory());
        }
        HostnameVerifier hostnameVerifier = getHostnameVerifier();
        if (hostnameVerifier != null) {
            // 设置 SDK 内部的上传下载支持自签证书
            SSLUtils.setHostnameVerifier(hostnameVerifier);
            // 并且把 Glide 设置成支持自签证书(glide 内部是 HttpsURLConnection)
            // SDK 内置的图片预览用的是 Glide
            HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
        }
        // 设置合并转发消息自签证书
        RongConfigCenter.featureConfig().setSSLInterceptor(new FeatureConfig.SSLInterceptor() {
            @Override
            public boolean check(SslCertificate sslCertificate) {
                return true;
            }
        });
    }

    private HostnameVerifier getHostnameVerifier() {
        HostnameVerifier hostnameVerifier =
                new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                };
        return hostnameVerifier;
    }

    private SSLContext getSslContext() {
        TrustManager tm[] = {
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {
                    Log.d("checkClientTrusted", "authType:" + authType);
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {
                    Log.d("checkServerTrusted", "authType:" + authType);
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }
        };

        SSLContext mySSLContext = null;
        try {
            mySSLContext = SSLContext.getInstance("TLS");
            mySSLContext.init(null, tm, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mySSLContext;
    }

如果使用的 IMLib 版本低于 2.10.6.3 版本,需要调用下面的 API , 参数传 true

/**
 * 设置建立 Https 连接时,是否使用自签证书。
 * <p> 此方法需要在 {@link #init(Context)}之前调用。</p>
 * <p> 如果不调用此方法, SDK 连接时会按默认证书处理</p>
 *
 * @param isEnable 是否使用自`预先格式化的文本`签证书。true 使用自签证书;false, 使用默认证书。
 */
public void enableHttpsSelfCertificate(final boolean isEnable)

方案二:在应用里声明允许明文传输

风险声明:允许明文传输可能导致 Google Play 无法上架。

通过下面配置,在 Android 9.0 手机上会仍然使用 http 连接,即明文传输的方式。

  1. 在应用的 res/xml 文件夹下新建 network_security_config.xml 文件

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <base-config cleartextTrafficPermitted="true" />
    </network-security-config>
    
  2. AndroidManifest.xmlapplication 节点下,配置允许明文传输的属性。

    <application
        android:name=".myApp"
        android:allowBackup="true"
        android:icon="@drawable/seal_app_logo"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
    

更多支持

如有疑问,欢迎提交工单