You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android 4.4-5.0中使用OkHttp支持TLS 1.0

解决Android 4.4 + OkHttp 3.10.0的SSL握手失败问题(支持TLS 1.0)

这个场景我帮不少开发者处理过,Android 4.4(API 19)的原生SSL库对TLS协议的支持确实有局限,再加上OkHttp 3.x的默认配置偏向高版本TLS,就容易出现你遇到的SSL handshake aborted错误。咱们一步步来搞定:

核心原因

Android 4.4的默认SSL实现(旧版本Conscrypt)没有默认启用TLS 1.0/1.1/1.2的全部组合,而OkHttp 3.10.0默认的TLS配置可能和服务器的要求不匹配,导致握手失败。

解决方案一:自定义OkHttp的SSL配置,强制启用TLS 1.0

直接修改你的OkHttpClient初始化代码,通过自定义SSLSocketFactory来指定支持的TLS版本:

1. 编写自定义SSLSocketFactory

import javax.net.ssl.*;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

// ... 其他导入代码

// 创建SSL上下文
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) {}

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) {}

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

// 自定义Socket Factory,强制启用TLS 1.0、1.1、1.2
SSLSocketFactory sslSocketFactory = new SSLSocketFactory() {
    private final SSLSocketFactory delegate = sslContext.getSocketFactory();

    @Override
    public String[] getDefaultCipherSuites() {
        return delegate.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return delegate.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
        Socket sslSocket = delegate.createSocket(socket, host, port, autoClose);
        enableTlsProtocols(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        Socket sslSocket = delegate.createSocket(host, port);
        enableTlsProtocols(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        Socket sslSocket = delegate.createSocket(host, port, localHost, localPort);
        enableTlsProtocols(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        Socket sslSocket = delegate.createSocket(host, port);
        enableTlsProtocols(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        Socket sslSocket = delegate.createSocket(address, port, localAddress, localPort);
        enableTlsProtocols(sslSocket);
        return sslSocket;
    }

    private void enableTlsProtocols(Socket socket) {
        if (socket instanceof SSLSocket) {
            ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"});
        }
    }
};

2. 配置OkHttpClient

把上面的Socket Factory和HostnameVerifier配置到你的OkHttpClient构建器中:

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(3600, TimeUnit.SECONDS)
        .readTimeout(3600, TimeUnit.SECONDS)
        .sslSocketFactory(sslSocketFactory, (X509TrustManager) sslContext.getTrustManagers()[0])
        .hostnameVerifier((hostname, session) -> {
            // 生产环境请替换为严格的主机名验证逻辑,这里是临时跳过验证
            return HostnameVerifier.DEFAULT.verify(hostname, session);
        })
        .build();

注意事项

  • 上面的X509TrustManager是简化版,生产环境一定要替换成严格的证书验证逻辑,避免安全风险(比如导入服务器的CA证书)。
  • HostnameVerifier也不要直接返回true,用系统默认的验证逻辑更安全。

解决方案二:引入Conscrypt库提升TLS兼容性

如果自定义配置还是不行,可以引入Google的Conscrypt库替换系统的SSL实现,它对老Android版本的TLS支持更完善:

1. 添加依赖

在你的build.gradle(Module级别)中添加:

implementation 'org.conscrypt:conscrypt-android:2.5.2'

2. 初始化Conscrypt

在应用启动时(比如Application的onCreate方法)初始化:

import org.conscrypt.Conscrypt;
import java.security.Security;

// ...

@Override
public void onCreate() {
    super.onCreate();
    // 把Conscrypt设置为优先使用的SSL提供者
    Security.insertProviderAt(Conscrypt.newProvider(), 1);
}

3. 正常创建OkHttpClient

此时不需要自定义SSLSocketFactory,直接用你原来的代码初始化即可,Conscrypt会自动处理TLS协议的兼容:

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(3600, TimeUnit.SECONDS)
        .readTimeout(3600, TimeUnit.SECONDS)
        .build();

这个方法的兼容性更好,推荐在需要兼容多个老Android版本的项目中使用。

内容的提问来源于stack exchange,提问作者Ata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:52:42