Xamarin.Android如何通过network_security_config.xml固定自签名证书
问题1:配置存在的问题及证书固定实现方案
你遇到的两个报错分别对应两个核心问题:
- 第一个
Trust anchor for certification path not found报错:Android的证书固定是信任链校验通过后的附加校验逻辑,不会替代原有信任锚验证流程。自签名证书不在系统默认信任锚列表中,仅配置pin值无法通过基础的证书信任校验。 - 第二个
Hostname not verified报错:Android 7.0及以上版本不再读取证书CN字段做主机名校验,仅校验证书的Subject Alternative Name(SAN)字段,你的证书未将IP地址填入IP类型的SAN条目,因此主机名校验不通过。
正确实现步骤:
- 重新生成自签名证书,将
192.168.0.199作为IP类型的SAN条目添加到证书中 - 保留你第二版配置里的信任锚(引入@raw下的自签名证书)和pin-set配置即可正常生效,注意pin值需对应证书公钥的SHA256哈希,而非整证书哈希。
问题2:获取证书SHA256 pin值的其他方式
你可以通过openssl命令直接生成,命令如下:
openssl x509 -in server.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
除此之外也可以通过OkHttp的CertificatePinner工具类、Android Studio网络 inspector的证书详情页获取对应pin值。
问题3:是否必须将证书文件添加为信任锚
如果是自签名证书,必须添加。如果是公共CA签发的证书,不需要单独添加,因为CA根证书已经内置在系统信任锚列表中。
Android的证书固定设计为附加防御能力,用来避免信任锚范围内的伪造证书风险,不会跳过基础的信任链校验逻辑,因此未被信任的证书即使pin值匹配也不会通过校验。
问题4:其他证书固定实现方案
- 代码层配置:使用OkHttp的
CertificatePinnerAPI动态配置pin值,无需编写XML网络安全配置,适合需要动态更新pin的场景。 - 自定义校验逻辑:自定义
X509TrustManager,自行实现证书公钥/全证书哈希比对逻辑,灵活度更高,但需注意避免编写空校验逻辑引入安全漏洞。 - WebView场景:重写
WebViewClient的onReceivedSslError方法,自行实现证书校验逻辑。
问题5:IP地址作为主机名的相关说明
IP地址允许作为主机名使用,仅需要满足证书配置要求:在生成证书时将IP地址添加到SAN字段的IP类型条目中,不要仅填在CN字段即可。配置完成后IP和域名的证书固定流程完全一致,直接将IP填入<domain>标签即可正常使用。
补充说明(针对你的更新疑问)
Android系统设计上不允许仅配置pin值跳过信任锚校验,核心原因是pin定位为第二层防御能力,仅用来缩小信任范围,而非替代整个证书校验体系。如果允许跳过信任锚校验直接匹配pin,很容易出现开发者忽略证书有效期、吊销状态等风险,反而降低通信安全性。
内容的提问来源于stack exchange,提问作者wierob
相关产品推荐
相关产品推荐

