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

Java/Python解决HTTP(S)主机名解析失败及TLSV1_UNRECOGNIZED_NAME错误

解决方案:访问epic7db.com的TLS与主机名问题

问题核心

目标网站epic7db.com的TLS配置存在特殊处理:程序解析主机名失败,直接用IP访问时触发TLSV1_UNRECOGNIZED_NAME错误,但浏览器可正常访问。这大概率是网站服务器对SNI(Server Name Indication)的校验逻辑异常,或证书与主机名的映射规则特殊。


Python 解决方案

针对requests代码,需要强制指定SNI主机名,同时确保请求头包含正确的Host字段,可通过自定义SSLAdapter实现:

import requests
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
import ssl

class SNIAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            ssl_version=ssl.PROTOCOL_TLS_CLIENT,
            server_hostname="epic7db.com"  # 强制指定SNI主机名
        )

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36',
    'Host': 'epic7db.com'  # 显式设置Host头
}

url = 'https://epic7db.com'
session = requests.Session()
session.mount('https://', SNIAdapter())

try:
    response = session.get(url, headers=headers)
    response.raise_for_status()
    print(response.content)
except Exception as e:
    print(f"错误: {e}")

若直接用IP访问,需保持Host头和SNI主机名一致:

url = 'https://157.230.84.20/heroes'
headers['Host'] = 'epic7db.com'
# 其余代码同上,SNIAdapter仍指定server_hostname为epic7db.com

Java/Kotlin 解决方案

你尝试清空SNI列表无效,可能是Java SSL上下文默认仍会自动添加SNI。可尝试以下两种方案:

方案1:强制设置正确的SNI主机名

取消注释SNI添加逻辑,确保SSL参数正确传递:

import java.net.URL
import javax.net.ssl.*

fun main() {
    // 信任所有证书(仅测试用,生产环境请勿使用)
    val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
        override fun checkClientTrusted(chain: Array<java.security.cert.X509Certificate>?, authType: String?) {}
        override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>?, authType: String?) {}
        override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> = arrayOf()
    })

    val sslContext = SSLContext.getInstance("TLS")
    sslContext.init(null, trustAllCerts, java.security.SecureRandom())

    val url = URL("https://epic7db.com")
    val sslParameters = SSLParameters()
    // 强制添加正确的SNI主机名
    val sniHostNames = mutableListOf<SNIHostName>(SNIHostName(url.host))
    sslParameters.serverNames = sniHostNames

    // 自定义SSLSocketFactory传递参数
    val wrappedFactory = object : SSLSocketFactoryWrapper(sslContext.socketFactory, sslParameters) {}

    HttpsURLConnection.setDefaultSSLSocketFactory(wrappedFactory)
    HttpsURLConnection.setDefaultHostnameVerifier { _, _ -> true }

    val conn = url.openConnection() as HttpsURLConnection
    conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36")
    
    try {
        val content = String(conn.inputStream.readAllBytes())
        println(content)
    } catch (e: Exception) {
        println("错误: ${e.message}")
    } finally {
        conn.disconnect()
    }
}

// 保留原SSLSocketFactoryWrapper辅助类
package http;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class SSLSocketFactoryWrapper extends SSLSocketFactory {

    private final SSLSocketFactory wrappedFactory;
    private final SSLParameters sslParameters;

    public SSLSocketFactoryWrapper(SSLSocketFactory factory, SSLParameters sslParameters) {
        this.wrappedFactory = factory;
        this.sslParameters = sslParameters;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        SSLSocket socket = (SSLSocket) wrappedFactory.createSocket(host, port);
        setParameters(socket);
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
            throws IOException, UnknownHostException {
        SSLSocket socket = (SSLSocket) wrappedFactory.createSocket(host, port, localHost, localPort);
        setParameters(socket);
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        SSLSocket socket = (SSLSocket) wrappedFactory.createSocket(host, port);
        setParameters(socket);
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        SSLSocket socket = (SSLSocket) wrappedFactory.createSocket(address, port, localAddress, localPort);
        setParameters(socket);
        return socket;
    }

    @Override
    public Socket createSocket() throws IOException {
        SSLSocket socket = (SSLSocket) wrappedFactory.createSocket();
        setParameters(socket);
        return socket;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return wrappedFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return wrappedFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        SSLSocket socket = (SSLSocket) wrappedFactory.createSocket(s, host, port, autoClose);
        setParameters(socket);
        return socket;
    }

    private void setParameters(SSLSocket socket) {
        socket.setSSLParameters(sslParameters);
    }
}

方案2:禁用SNI扩展

若方案1无效,直接禁用SNI:在JVM启动参数添加-Djsse.enableSNIExtension=false,或在代码开头设置:

System.setProperty("jsse.enableSNIExtension", "false")

关键说明

  1. 网站特殊配置可能要求SNI字段必须严格匹配epic7db.com,部分HTTP客户端自动处理逻辑不符合要求;
  2. 生产环境请勿使用信任所有证书的代码,建议导入网站根证书做校验;
  3. 浏览器能正常访问是因为其SNI和Host头的处理逻辑更兼容这类特殊配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:00:59