You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin应用调用C# .NET 6 API遇SSL错误求助

Android调用.NET 6 API SSL信任问题解决方案

问题核心

Android应用调用.NET 6 API时抛出Trust anchor for certification path not found错误,但手机浏览器(Swagger)和Postman可正常访问API,部分调试操作引发End of stream错误。

已尝试方案回顾

  • 关闭API的SSL及认证
  • 添加防火墙规则
  • 通过OkHttpClient+Retrofit传递SSL证书
  • 在domain-config中允许ClearText

针对性解决方案

1. 确认证书格式与导出流程

.NET开发环境的自签证书默认存放在%USERPROFILE%\.aspnet\https目录,需导出**Base-64编码的X.509(.CER)**格式证书:

  • 右键证书文件 → 打开 → 切换到「详细信息」标签 → 点击「复制到文件」
  • 选择「Base-64编码X.509(.CER)」,完成导出后将文件重命名为小写(如certificate.cer),放入Android项目的res/raw目录。

2. 修正OkHttp证书加载代码(修复流泄漏问题)

原代码未关闭证书输入流,可能引发End of stream错误,修改后代码:

object ServiceGenerator {

    private fun generateSecureOkHttpClient(context: Context): OkHttpClient {
        val httpClientBuilder = OkHttpClient.Builder()
            .readTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)

        val cf = CertificateFactory.getInstance("X.509")
        // 使用use块自动关闭输入流,避免资源泄漏
        val ca = context.resources.openRawResource(R.raw.certificate).use { caInput ->
            cf.generateCertificate(caInput)
        }

        val keyStoreType = KeyStore.getDefaultType()
        val keyStore = KeyStore.getInstance(keyStoreType)
        keyStore.load(null, null)
        keyStore.setCertificateEntry("ca", ca)

        val tmfAlgorithm: String = TrustManagerFactory.getDefaultAlgorithm()
        val tmf: TrustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm)
        tmf.init(keyStore)

        val sslContext = SSLContext.getInstance("TLS")
        sslContext.init(null, tmf.trustManagers, SecureRandom())

        return httpClientBuilder
            .sslSocketFactory(sslContext.socketFactory, tmf.trustManagers[0] as X509TrustManager)
            // 开发阶段临时跳过主机名验证(生产环境必须移除)
            .hostnameVerifier { _, _ -> true }
            .build()
    }

    fun generateService(context: Context): ApiInterface {
        return Retrofit.Builder()
            .baseUrl("https://192.168.50.41:5000/api/")
            .client(generateSecureOkHttpClient(context))
            .addConverterFactory(JacksonConverterFactory.create())
            .build()
            .create(ApiInterface::class.java)
    }
}

3. 简化网络安全配置,避免冲突

确保network_security_config.xml与OkHttp配置一致,开发阶段可允许明文流量辅助调试:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">192.168.50.41</domain>
        <trust-anchors>
            <certificates src="@raw/certificate"/>
            <certificates src="system"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

同时需在AndroidManifest.xml中引用该配置:

<application
    ...
    android:networkSecurityConfig="@xml/network_security_config"
    ...>
</application>

4. 验证.NET API证书绑定(可选)

若API证书存在异常,可在Program.cs中显式指定证书路径与密码:

builder.WebHost.UseKestrel(options =>
{
    // 替换为你的证书文件名与密码(默认.NET自签证书密码为password)
    options.ListenAnyIP(5000, o => o.UseHttps("FriendZone.API.pfx", "password"));
    options.ListenAnyIP(5001, o => o.UseHttps("FriendZone.API.pfx", "password"));
});

排查关键点

  • 证书格式必须为X.509的CER格式,PFX证书无法直接被Android识别
  • 输入流必须正确关闭,否则会引发流相关错误
  • 开发阶段跳过主机名验证仅用于调试,生产环境需确保证书的SAN字段包含API的IP/域名

内容的提问来源于stack exchange,提问作者bilbsy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:11:08