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

Android Q预览版TLSv1自签名证书握手报SSLV3_ALERT_CERTIFICATE_UNKNOWN错误

Android Q预览版TLSv1自签名证书握手失败解决方案

针对你遇到的SSLV3_ALERT_CERTIFICATE_UNKNOWN握手失败问题,结合Android Q预览版的特性限制,给你几个针对性的解决思路:

1. 升级TLS协议版本到TLSv1.2+

Android Q开始默认禁用了TLSv1.0和TLSv1.1,你当前使用的TLSv1协议已不在系统默认允许范围内。修改createSSLSocket方法,指定使用TLSv1.2:

private ServerSocket createSSLSocket() throws Exception {
    // 初始化SSLContext为TLSv1.2
    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    // 传入自定义TrustManager处理自签名证书信任
    sslContext.init(null, getCustomTrustManagers(), new SecureRandom());
    
    SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
    SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket();
    // 强制启用TLSv1.2协议
    serverSocket.setEnabledProtocols(new String[]{"TLSv1.2"});
    return serverSocket;
}

2. 自定义TrustManager信任自签名证书

Android Q对证书链验证更严格,需让应用明确信任你的自签名证书,可通过自定义TrustManager实现:

private TrustManager[] getCustomTrustManagers() throws Exception {
    // 读取res/raw目录下的自签名证书文件(示例命名为my_self_signed.crt)
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream certInputStream = getResources().openRawResource(R.raw.my_self_signed);
    Certificate caCert;
    try {
        caCert = cf.generateCertificate(certInputStream);
    } finally {
        certInputStream.close();
    }

    // 将证书加载到KeyStore
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null, null);
    keyStore.setCertificateEntry("custom_ca", caCert);

    // 生成信任管理器
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    return tmf.getTrustManagers();
}

3. 确保证书包含SAN字段

Android Q要求证书必须包含Subject Alternative Name(SAN)字段,即使是本地回环地址127.0.0.1也需要声明。如果你的自签名证书没有该字段,重新生成时可通过OpenSSL添加:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -addext "subjectAltName=IP:127.0.0.1"

4. 移除被禁止的反射调用

日志中getOriginalHostName()的反射调用被Android Q拒绝,虽不是握手失败直接原因,但可能引发潜在问题。改用公开APIInetAddress.getHostName()获取主机名即可。

按照上述步骤调整后,应该能解决Android Q预览版中的SSL握手失败问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:10:46