Android Nougat下CertPathValidatorException问题咨询:证书信任锚缺失
嘿,我之前处理旧Symantec证书时碰到过一模一样的问题,尤其是在Android 7.0(Nougat)及以上版本,给你拆解下原因和可行的解决方案:
问题根源
Android Nougat开始,Google因为Symantec的证书信任体系问题,逐步移除了一批旧的Symantec根证书,你提到的Symantec Class 3 Secure Server CA - G4正好在被移除的列表里。这就是为什么你的手机系统证书库找不到它,导致证书路径验证失败;而openssl返回的Verify return code:21,通常也和证书链不完整/根证书不被信任直接相关。
可行的解决方案(无需跳过验证)
当然可以不用那个不安全的“不信任时返回true”临时方案,正确的做法是在应用内手动导入并信任该CA证书,具体步骤如下:
1. 准备CA证书文件
确保你拿到的是Symantec Class 3 Secure Server CA - G4的根证书(不是服务器的叶子证书),格式可以是.crt或.pem。你可以用以下命令验证证书信息:
openssl x509 -in symantec_g4_ca.crt -text -noout
确认输出里的Issuer和Subject都是这个CA的信息。
2. 配置network_security_config
- 将证书文件放到
res/raw目录下(如果没有raw目录就新建一个) - 在
res/xml目录下创建network_security_config.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <!-- 保留系统默认信任的所有证书 --> <certificates src="system" /> <!-- 添加我们自定义的Symantec CA证书 --> <certificates src="@raw/symantec_g4_ca" /> </trust-anchors> </base-config> </network-security-config>
注意:@raw/symantec_g4_ca里的名称要和你放在raw目录下的证书文件名一致(不带后缀)。
3. 在Manifest中引用配置
打开AndroidManifest.xml,在application标签里添加:
android:networkSecurityConfig="@xml/network_security_config"
你可能遗漏的配置点
如果你之前试过network_security_config但没生效,大概率是以下问题之一:
- 证书文件不对:用了服务器的叶子证书而非CA根证书
- 配置里没保留
system证书:如果只加了自定义CA,会导致其他正常HTTPS请求失败 - Manifest里没正确引用配置文件:检查路径拼写是否正确
- 证书格式问题:确保证书是PEM或DER格式,Android支持的格式
为什么临时绕过能行?
那个“不信任时返回true”的代码本质是跳过了所有证书验证,这会让你的应用暴露在中间人攻击的风险里,绝对不能用于正式环境,一定要替换成上面的安全方案。
内容的提问来源于stack exchange,提问作者david

