Android模拟器连接本地localhost API遭遇证书错误求助
解决Android模拟器访问本地.NET API的证书问题
一、先搞定本地API的证书生成
- 生成自签名证书时必须包含模拟器能识别的地址,不然浏览器和APP都不认:
用OpenSSL生成带SAN字段的证书,命令如下:
这里openssl req -x509 -newkey rsa:4096 -keyout local_api.key -out local_api.crt -days 365 -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost,IP:10.0.2.2"10.0.2.2是Android模拟器映射本地主机的固定IP,必须加到证书里。 - 把证书配置到你的API项目的Kestrel中,比如在
Program.cs里:builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(5001, opts => { opts.UseHttps("local_api.crt", "local_api.key"); }); });
二、正确给模拟器安装系统级证书
Android 7+之后,用户手动安装的证书不会被系统应用(包括内置浏览器)信任,必须放到系统证书目录:
- 把刚才生成的
local_api.crt推送到模拟器:
注意:只有API 24及以上的模拟器支持adb root adb remount adb push local_api.crt /system/etc/security/cacerts/ adb shell chmod 644 /system/etc/security/cacerts/local_api.crt adb rebootadb root和remount,低版本可以在系统设置里找“安全”→“安装证书”,选择“系统”类别(部分机型可能需要解锁OEM)。
三、WebView的证书信任配置
就算系统信任了证书,WebView默认还是会拦截,得自定义WebViewClient:
- 在Android平台项目里写个自定义WebViewClient:
public class TrustLocalApiWebViewClient : WebViewClient { public override void OnReceivedSslError(Android.Webkit.WebView view, SslErrorHandler handler, SslError error) { // 只在调试环境用,发布版必须删掉这段 if (error.PrimaryError == SslError.SslUnrecognizedIssuer && error.Certificate.IssuedBy.DnName.Contains("localhost")) { handler.Proceed(); } else { base.OnReceivedSslError(view, handler, error); } } } - 给Maui的WebView加自定义渲染器:
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))] namespace YourAppName.Platforms.Android { public class CustomWebViewRenderer : WebViewRenderer { public CustomWebViewRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<WebView> e) { base.OnElementChanged(e); if (Control != null) { Control.SetWebViewClient(new TrustLocalApiWebViewClient()); } } } }
四、Mitmproxy的正确用法(如果还要用)
之前没用成大概率是代理和证书位置不对:
- 启动Mitmproxy后,在模拟器设置里配置代理为
10.0.2.2:8080(Mitmproxy默认端口8080)。 - 把Mitmproxy的CA证书(在
~/.mitmproxy/mitmproxy-ca-cert.crt)按照步骤二的方法安装到模拟器系统证书目录,不要装成用户证书。
五、调试验证顺序
- 先在模拟器内置浏览器访问
https://10.0.2.2:5001/你的API路径,确认没有证书错误。 - 测试C#代码的HttpClient调用,调试环境下可以临时跳过证书验证(发布版绝对不能这么做):
var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (sender, cert, chain, errors) => { return errors == SslPolicyErrors.None || cert.Subject.Contains("localhost"); } }; var httpClient = new HttpClient(handler);
内容的提问来源于stack exchange,提问作者Mark Evans
相关产品推荐
相关产品推荐

