Android应用访问本地ASP.NET API时证书主机名不匹配的解决方法
解决方案:Android访问本地API证书主机名不匹配问题
核心原因
错误源于SSL证书绑定的是服务器计算机名,但你用IP地址访问时,客户端会验证请求主机名与证书的SAN(主题备用名称)/CN(通用名称)是否一致,不匹配就会触发安全校验失败。
具体解决办法
1. 代码层面指定验证主机名(无需依赖外部DNS)
可以在Android的网络请求中手动指定要验证的主机名,让客户端用证书绑定的计算机名完成校验,而非使用IP地址。以OkHttp为例:
val client = OkHttpClient.Builder() .sslSocketFactory( SSLContext.getDefault().socketFactory, X509TrustManagerImpl() // 可使用默认信任管理器,或自定义信任逻辑 ) .hostnameVerifier { _, session -> // 替换成你的服务器计算机名,比如"DESKTOP-XYZ789" session.peerHost == "你的服务器计算机名" } .build()
注意:自定义hostnameVerifier时,务必确保你信任目标服务器,避免引入安全风险。
2. 修改Android设备hosts文件(无需改动代码)
如果你的Android设备已root,直接修改/system/etc/hosts文件,添加IP与计算机名的映射:
你的服务器IP地址 你的服务器计算机名
示例:192.168.1.105 DESKTOP-XYZ789,之后在Android应用中用计算机名访问API,本地解析会直接指向目标IP,证书校验即可通过。
3. 重新生成包含IP的SSL证书
若条件允许,给ASP.NET API重新生成包含服务器IP地址的SSL证书:
- 在IIS中重新申请证书,在SAN字段里添加服务器IP;
- 或用
dotnet dev-certs命令生成开发证书:
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\api.pfx -p 自定义密码 --trust --ip 192.168.1.105
这样无论用IP还是计算机名访问,证书校验都能通过。
4. 临时忽略证书验证(仅测试环境使用)
如果只是测试阶段,可临时跳过证书校验,但绝对禁止用于生产环境:
val unsafeClient = OkHttpClient.Builder() .sslSocketFactory(createUnsafeSSLSocketFactory(), trustAllCerts[0] as X509TrustManager) .hostnameVerifier { _, _ -> true } .build() private fun createUnsafeSSLSocketFactory(): SSLSocketFactory { val sslContext = SSLContext.getInstance("SSL") sslContext.init(null, trustAllCerts, SecureRandom()) return sslContext.socketFactory } private val trustAllCerts = arrayOf(object : X509TrustManager { override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray() })
内容的提问来源于stack exchange,提问作者Andrew Taylor
相关产品推荐
相关产品推荐

