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

Android 9.0双向SSL认证出现handshake failed握手失败问题求助

我来帮你分析下这个问题——Android 9.0(API 28)开始引入了不少影响SSL/TLS握手的系统级变更,这大概率是导致你双向SSL认证失败的核心原因,下面给你拆解几个关键排查点和解决方案:

核心问题根源

Android 9.0及以上版本对网络安全做了更严格的限制,主要涉及这几点:

  • 默认仅支持TLS 1.2及更高版本,禁用了TLS 1.0/1.1,如果你的服务器仍依赖旧协议,直接会握手失败。
  • 新增了**网络安全配置(Network Security Configuration)**强制规范,默认不信任用户自定义的CA证书(双向SSL里的客户端证书、服务器CA都属于这类),必须显式声明信任。
  • 对证书的合规性要求更高:SHA-1签名的证书会被直接拒绝,证书链不完整、域名不匹配、过期的证书也会触发验证失败。
分步解决方案

1. 确认并对齐TLS协议版本

首先检查你的服务器是否支持TLS 1.2+。如果服务器暂无法升级,可临时在应用中放宽协议限制(不推荐长期使用,建议尽快升级服务器):
假设你使用OkHttp作为网络库,可这样配置:

ConnectionSpec tlsSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
    .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0)
    .build();

OkHttpClient client = new OkHttpClient.Builder()
    .connectionSpecs(Arrays.asList(tlsSpec))
    .build();

2. 配置网络安全配置文件

Android 9.0+默认不允许应用信任自定义CA,你需要创建并配置网络安全规则:

  1. 在res/xml目录下新建network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <!-- 替换为你的服务器域名,includeSubdomains=true表示信任子域名 -->
        <domain includeSubdomains="true">your-server-domain.com</domain>
        <!-- 信任服务器CA证书,将证书文件放在res/raw目录下 -->
        <trust-anchors>
            <certificates src="@raw/server_ca_cert" />
            <!-- 如果需要同时信任系统默认CA,添加这行 -->
            <certificates src="system" />
        </trust-anchors>
        <!-- 开启双向SSL要求 -->
        <client-auth>required</client-auth>
        <!-- 配置客户端证书来源(密钥库文件放在res/raw,替换密码) -->
        <client-certificates>
            <certificates src="@raw/client_keystore" password="your-keystore-password" />
        </client-certificates>
    </domain-config>
</network-security-config>
  1. 在AndroidManifest.xml的<application>标签中引用该配置:
<application
    ...
    android:networkSecurityConfig="@xml/network_security_config">
    ...
</application>

3. 检查证书合规性

  • 确保客户端证书、服务器CA证书均使用SHA-256及以上的签名算法,Android 9.0+会直接拒绝SHA-1签名的证书。
  • 验证证书链完整性:客户端证书需包含完整的中间CA链,服务器返回的证书链也不能缺失中间节点。
  • 确认证书未过期,且域名与服务器地址完全匹配(若使用域名型SSL证书)。

4. 开启调试日志定位细节

如果仍失败,可开启SSL调试日志查看握手过程中的具体错误:

// 在应用启动时添加这行代码
System.setProperty("javax.net.debug", "ssl");

之后在Logcat中搜索SSL相关日志,就能看到握手时的协议协商、证书验证等细节,快速定位失败环节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:54:10