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

Android 4.1-4.4设备出现OkHttp SSLHandshakeException握手失败求助

解决Android 4.1-4.4设备上的SSL握手失败问题

先看看你提供的错误日志:

04-23 17:17:38.434 21599-21956/ D/NativeCrypto: ssl=0x0 NativeCrypto_SSL_interrupt
04-23 17:17:38.435 21599-21956/ D/OkHttp: <-- HTTP FAILED: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x635d8808: SSL库执行失败,通常为协议错误 error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x5e6c46fd:0x00000000)

这个问题我处理过很多次,本质就是Android 4.1到4.4(对应API 16-19)的系统默认SSL/TLS栈跟不上现代服务器的要求了——这些版本默认没开启TLS 1.2支持,而现在几乎所有服务器都禁用了不安全的SSLv3和旧版TLS(比如TLS 1.0),握手时两边谈不拢就失败了。结合你日志里用的是OkHttp,给你几个实操性的解决办法:

1. 给OkHttp强制开启TLS 1.2

其实Android 4.1+底层已经支持TLS 1.2,只是默认没启用。你可以通过自定义OkHttpClient配置来打开这个开关,同时指定兼容的连接规范:

首先写一个自定义的Socket工厂,用来强制旧设备使用TLS 1.2:

public class Tls12SocketFactory extends SSLSocketFactory {
    private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
    private final SSLSocketFactory delegate;

    public Tls12SocketFactory(SSLSocketFactory delegate) {
        this.delegate = delegate;
    }

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

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

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return patchSocket(delegate.createSocket(s, host, port, autoClose));
    }

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

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

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

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

    private Socket patchSocket(Socket socket) {
        if (socket instanceof SSLSocket) {
            ((SSLSocket) socket).setEnabledProtocols(TLS_V12_ONLY);
        }
        return socket;
    }
}

然后获取系统默认的信任管理器,用来配置OkHttpClient:

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
    throw new IllegalStateException("Unexpected default trust managers: " + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];

最后构建支持TLS 1.2的OkHttpClient:

OkHttpClient client = new OkHttpClient.Builder()
    .connectionSpecs(Arrays.asList(
        ConnectionSpec.MODERN_TLS,
        ConnectionSpec.COMPATIBLE_TLS
    ))
    .sslSocketFactory(new Tls12SocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault()), trustManager)
    .build();

2. 降级到兼容的OkHttp版本

如果你现在用的是OkHttp 4.x或者更高版本,得注意这些版本已经放弃支持Android 4.x(API低于21)了。你需要把OkHttp降级到3.12.x系列,这是官方支持Android 4.1+的最后一个分支。修改你的build.gradle(Module级别):

implementation 'com.squareup.okhttp3:okhttp:3.12.13'

3. 服务器端配置优化(如果有权限)

如果你能调整服务器的SSL设置,尽量让服务器同时支持TLS 1.2和Android 4.x兼容的加密套件——别只开最新的那些旧设备不认识的套件。你可以用本地的SSL测试工具检查服务器兼容性,确保它对Android 4.4设备是友好的。

这些方案都是经过实际项目验证的,核心就是让客户端和服务器在协议版本和加密套件上达成一致,就能解决这个握手失败的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:09:17