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

Ktor-client使用IP地址发起HTTPS请求遇主机名未验证问题

解决Ktor Client使用IP访问HTTPS时的Hostname验证错误

问题原因

你配置的TrustManager仅跳过了证书信任校验,但OkHttp默认会执行主机名验证:检查服务器证书的SAN(Subject Alternative Name)或CN(Common Name)字段是否包含请求的IP地址。如果证书未绑定目标IP,就会抛出Hostname xxx not verified错误。

解决方案

方案1:临时禁用主机名验证(仅测试环境)

在OkHttp引擎配置中添加自定义hostnameVerifier,直接返回true跳过验证:

engine {
    config {
        // 原有SSL配置
        val sslContext: SSLContext = SSLContext.getInstance("SSL")
        sslContext.init(null, trustAllCerts, SecureRandom())
        sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
        
        // 跳过主机名验证
        hostnameVerifier { _, _ -> true }
    }
}

注意:此方法仅适用于测试环境,生产环境禁用会导致中间人攻击风险。

方案2:自定义验证逻辑(生产环境推荐)

针对特定IP做白名单,同时保留域名请求的默认验证逻辑:

engine {
    config {
        // 原有SSL配置...
        
        hostnameVerifier { hostname, session ->
            // 允许指定IP通过验证
            hostname == "192.168.1.100" ||
            // 保留默认验证,兼容域名请求
            OkHostnameVerifier.INSTANCE.verify(hostname, session)
        }
    }
}

方案3:修改服务器证书(最安全)

让服务器证书的SAN字段添加目标IP地址,这样默认的主机名验证器就能正常通过,无需修改客户端代码。这是生产环境的最优解。

更换为CIO引擎的配置方式

如果切换到Ktor的CIO引擎,配置逻辑类似:

import io.ktor.client.engine.cio.*

val client = HttpClient(CIO) {
    engine {
        sslManager = {
            SSLContext.getInstance("SSL").apply {
                init(null, trustAllCerts, SecureRandom())
            }.socketFactory
        }
        hostnameVerifier = { hostname, session ->
            hostname == "192.168.1.100" || defaultHostnameVerifier.verify(hostname, session)
        }
    }
}

内容的提问来源于stack exchange,提问作者Patrik Csikós

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:45:37