Android应用SSL连接证书验证失败,如何安全修复?
修复方案
问题根源
从openssl s_client的输出可以明确:服务器返回的证书链缺少关键中间证书(Thawte TLS RSA CA G1)。服务器的终端证书(层级0)签发者是Thawte TLS RSA CA G1,但返回的证书链里并没有这个证书,导致客户端无法构建完整的信任链路,最终触发CERTIFICATE_VERIFY_FAILED验证错误。
具体修复步骤
获取缺失的中间证书
下载Thawte TLS RSA CA G1的PEM格式证书(可从官方证书库获取),将其添加到应用资源文件中(命名示例:thawte_tls_rsa_ca_g1.pem),确保资源的生成操作设置为Embedded Resource。调整代码,修复证书验证逻辑
你当前代码错误地将证书添加到ClientCertificates(这是用于双向认证的客户端证书,和本次服务器证书验证问题无关),需改为将中间证书加入信任验证链:
public static async Task<Usuario> Login(UsuarioLogin login) { try { // 加载缺失的中间证书 var intermediateCert = new X509Certificate2(Resources.thawte_tls_rsa_ca_g1); var handler = new HttpClientHandler(); handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12; // 自定义证书验证逻辑,补全信任链 handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { // 将中间证书加入验证链的额外存储 chain.ChainPolicy.ExtraStore.Add(intermediateCert); // 重新构建证书链 chain.Build((X509Certificate2)cert); // 检查验证状态,仅允许合法的无错误/根证书已信任状态 foreach (var status in chain.ChainStatus) { if (status.Status != X509ChainStatusFlags.NoError && status.Status != X509ChainStatusFlags.UntrustedRoot) { return false; } } return true; }; // 仅当服务器要求双向认证时保留以下代码,否则可移除 handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ClientCertificates.Add(new X509Certificate2(Resources.certificadopem)); using (HttpClient client = new HttpClient(handler)) { var json = JsonConvert.SerializeObject(login); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await client.PostAsync(ModelUrl, content); response.EnsureSuccessStatusCode(); var response2 = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Usuario>(response2); } } catch (Exception e) { Console.WriteLine(e.ToString()); throw; } }
- 验证修复效果
重新测试API调用,确认证书验证通过。若仍有问题,检查:- 下载的中间证书CN是否为
Thawte TLS RSA CA G1 - 应用资源是否正确加载
- 下载的中间证书CN是否为
额外说明
- 绝对不要直接禁用证书验证(如设置
ServerCertificateCustomValidationCallback = (sender, cert, chain, errors) => true;),这会彻底破坏SSL安全机制。 - 最优先的解决方案是联系服务器运维方,在服务器上部署完整的证书链(包含所需中间证书),客户端无需任何修改即可恢复正常。
内容的提问来源于stack exchange,提问作者Gabic
相关产品推荐
相关产品推荐

