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
相关产品推荐
相关产品推荐

