【问题标题】:retrofit + okhttp on android 4 sslandroid 4 ssl 上的改造 + okhttp
【发布时间】:2019-04-16 07:08:45
【问题描述】:

我发现 android 4 不能很好地使用 ssl ,当尝试使用 https 联系 api 时会导致崩溃

javax.net.ssl.SSLException:SSL 握手中止:ssl=0xb8dbad20:系统调用期间 I/O 错误,对等方重置连接

这是我从其他类似问题中尝试过的:

   if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
        try {
            Logger.e("under lolipop");
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[] { new MyTrustManager() }, new SecureRandom());
            client.sslSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            Logger.e("HTTPS"+ e.getMessage() );
        }
    }

这对结果没有影响

还有

 if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {

        try {
            client.sslSocketFactory(new TLSSocketFactory(), (X509TrustManager)trustAllCerts[0])
                    .build();
            Logger.e("SETUP TRUST SSL");
            return client.build();
        } catch (KeyManagementException e) {
            Logger.e("SETUP TRUST SSL Failed "+e.getMessage());

            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            Logger.e("SETUP TRUST SSL Failed "+e.getMessage());

            e.printStackTrace();
        }
    }
    return client.build();

}
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[0];
    }
} };

这段代码给出了一个不同的错误:

java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。

有没有办法解决这个问题,我必须支持android 4并且还要使用https,

任何帮助都可以!

【问题讨论】:

标签: android okhttp3


【解决方案1】:

前段时间,当我们的后端放弃对 TLS 1.0 和 1.1 的支持时,我在 Android 4.4 上遇到了类似的问题。我通过使用 Google Play Services ProviderInstaller 安装新的安全提供程序解决了这个问题。

在你的应用程序 gradle.build 文件中添加

implementation "com.google.android.gms:play-services-auth:16.0.1"

尽早在您的启动活动中调用ProviderInstaller.installIfNeeded()。这是一个尝试安装提供程序的示例方法:

private static void installGooglePlayServicesProvider(Context context) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { //Devices with Android 5.1+ should support TLS 1.x out of the box
        try {
            ProviderInstaller.installIfNeeded(context);
        } catch (GooglePlayServicesRepairableException e) {
            Log.e("ProviderInstaller", "Google Play Services is out of date!", e);
            GoogleApiAvailability.getInstance().showErrorNotification(context, e.getConnectionStatusCode());
        } catch (GooglePlayServicesNotAvailableException e) {
            Log.e("ProviderInstaller", "Google Play Services is unavailable!", e);
        }
    }
}

有关 ProviderInstaller 的更多信息,请参阅 Goolge 开发者页面: Patch the security provider with ProviderInstaller

使用 TLS 1.2 时,您可能必须在某些设备上强制启用支持。 看看下面的文章和他们的Tls12SocketFactory 实现:Working with TLS 1.2 on Android 4.4 and Lower

【讨论】:

  • installGooglePlayServicesProvider 是否会提示某些屏幕?还是在幕后工作?
  • 另外,当我使用 Tls12SocketFactory 时它不起作用,我使用的是匕首,这可能是问题吗?
【解决方案2】:

Okhttp 3.13.x 已放弃对 TLS1.2 及更低版本的支持,仅支持 Android API 21+。您必须使用 Okhttp 3.12.x 版本分支才能在 Android 4.x 设备上使用它。

更多here

【讨论】:

    猜你喜欢
    • 2014-05-02
    • 2015-12-28
    • 1970-01-01
    • 2014-10-21
    • 2021-03-24
    • 2016-01-25
    • 2014-07-12
    • 2014-03-02
    • 1970-01-01
    相关资源
    最近更新 更多