retrofit + okhttp on android 4 ssl

5

我发现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。
任何帮助都可以!

你能给我试用的URL吗? - Vishal G. Gohel
我做不到,你想让我尝试什么? - yanivtwin
您可以使用在线工具 https://www.sslshopper.com/ssl-checker.html 检查SSL是否已正确应用于服务器端。 - Vishal G. Gohel
是的,它返回所有正数。 - yanivtwin
可能是重复的问题:Retrofit在特定版本的Android上无法工作 - Martin Zeitler
2个回答

11

我之前在Android 4.4遇到了类似的问题,当时我们的后端停止支持TLS 1.0和1.1。我通过安装Google Play服务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的信息,请参阅Google开发者页面:使用ProviderInstaller进行安全提供者补丁 在使用TLS 1.2时,您可能需要在某些设备上强制启用支持。请查看以下文章及其Tls12SocketFactory实现:在Android 4.4及以下版本中使用TLS 1.2

安装Google Play服务提供程序是否应该提示一些屏幕?还是它在后台工作? - yanivtwin
另外,当我使用Tls12SocketFactory时它不起作用,我正在使用Dagger,这可能是问题吗? - yanivtwin

1
Okhttp 3.13.x不再支持TLS1.2及以下版本,只支持Android API 21+。如果要在Android 4.x设备上使用它,您需要使用Okhttp 3.12.x版本分支。

更多信息请点击此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接