.NET MAUI Android应用调用IIS本地HTTPS接口时SSLPeerUnverifiedException(主机名未验证)问题的解决方法
嘿,我看了你遇到的这个SSL主机名验证问题,咱们一步步来排查解决。你已经做了不少基础配置,但可能在几个细节上还有遗漏,导致Android端还是不认这个证书的主机名。
一、先确认IIS的SSL证书和绑定是否真的正确生效
你用PowerShell生成证书的时候指定了DnsName = "localhost", "192.168.100.2",这一步是对的,但咱们要确认证书的SAN(主题备用名称)里确实包含了这个IP地址:
- 打开
mmc,添加证书管理单元(本地计算机-个人) - 找到你生成的那个证书,右键-属性-详细信息,找主题备用名称,确认里面有
IP Address=192.168.100.2和DNS Name=localhost - 另外,检查IIS的绑定:打开IIS管理器,找到默认网站的HTTPS绑定,确认IP地址是
192.168.100.2,端口443,证书选的是你生成的那个。
另外,你用PowerShell做的绑定里,New-WebBinding的-HostHeader "localhost"可能有问题——当你绑定IP地址的时候,HostHeader应该留空,否则IIS会把这个绑定和localhost的域名绑定关联,而不是IP。你可以修改这个PowerShell命令:
New-WebBinding -Name "Default Web Site" -IPAddress "192.168.100.2" -Port 443 -Protocol "https" -SslFlags 1
去掉-HostHeader "localhost",因为IP绑定不需要主机头,这样IIS才能正确响应来自192.168.100.2:443的请求。
二、修正Android网络安全配置的细节
你的network_security_config.xml框架是对的,但有几个细节要调整:
<?xml version="1.0" encoding="utf-8" ?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">localhost</domain> <domain includeSubdomains="false">192.168.100.2</domain> <!-- IP地址没有子域名,设为false更准确 --> <trust-anchors> <certificates src="@raw/iis_ssl_server_certificate"/> </trust-anchors> </domain-config> </network-security-config>
- 把IP地址对应的
includeSubdomains改成false,IP不存在子域名,这个设置能避免不必要的匹配逻辑干扰 - 确认
raw目录下的PEM文件命名完全和配置里的一致,且Build Action已经设为AndroidResource
三、MAUI Android代码层面的优化(可选但推荐)
你现在用的是原生HttpsURLConnection,Android端对这种原生API的主机名验证逻辑比较严格,换成MAUI封装的HttpClient会更省心,它会自动适配你配置的网络安全规则:
using System.Net.Http; using System.Text; var httpClient = new HttpClient(); httpClient.Timeout = TimeSpan.FromSeconds(10); httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("SmsGateway/1.0"); httpClient.DefaultRequestHeaders.Accept.ParseAdd("*/*"); var content = new StringContent(strRequestBody, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync("https://192.168.100.2:443/medservices/ReceiveWebhooks.php", content); isSent = response.IsSuccessStatusCode;
代码更简洁,也能减少原生API带来的适配问题。
如果一定要保留HttpsURLConnection,可以临时加一个自定义主机名验证器(注意:生产环境不建议这么做,仅调试用):
if(connection != null) { // 其他配置代码... // 添加自定义主机名验证逻辑 connection.HostnameVerifier = (hostname, session) => hostname.Equals("192.168.100.2") || hostname.Equals("localhost"); // 后续输出流、响应处理代码... }
这个验证器会检查请求的主机名是否是你指定的IP或localhost,符合就通过验证。
四、端到端测试确认
- 先在电脑上用浏览器打开
https://192.168.100.2/medservices/ReceiveWebhooks.php,确认证书显示为信任状态 - 用
curl测试:curl -v https://192.168.100.2/medservices/ReceiveWebhooks.php,看是否能正常连接,无SSL错误 - 最后运行MAUI Android应用测试POST请求
如果还是有问题,你可以在Android Studio的Logcat里搜索X509TrustManager或SSLPeerUnverified相关的日志,能帮你精准定位是证书不信任还是主机名验证失败。
按照这些步骤调整后,应该就能解决这个SSL主机名验证的问题了,有什么细节问题随时说~




