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

Apache HttpClient 4.5.13切换主机名验证器后证书匹配异常求助

问题描述

我将Apache HttpClient 4.5.13的SSLConnectionSocketFactory主机名验证器从NoopHostnameVerifier改为DefaultHostnameVerifier,修改前后代码如下:

修改前代码:

final SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);

修改后代码:

final SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null, new DefaultHostnameVerifier(PublicSuffixMatcherLoader.getDefault()));

此后访问https://foo.s3.amazonaws.com/fileName.csv时抛出SSL验证异常,报错信息:

Certificate for <foo.s3.amazonaws.com> doesn't match any of the subject alternative names:[*.s3.amazonaws.com, s3.amazonaws.com]

完整报错堆栈:

javax.net.ssl.SSLPeerUnverifiedException: Certificate for <foo.s3.amazonaws.com> doesn't match any of the subject alternative names: [*.s3.amazonaws.com, s3.amazonaws.com]
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:507)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:437)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)

该问题仅在生产环境出现,本地无法复现,请问可能是什么原因导致的?

可能原因分析
  • 公共后缀匹配逻辑差异:DefaultHostnameVerifier搭配PublicSuffixMatcherLoader.getDefault()后,会依据公共后缀列表验证域名。如果生产环境的公共后缀数据将s3.amazonaws.com识别为公共后缀,那么*.s3.amazonaws.com通配符只能匹配该后缀前的一级域名,无法匹配foo.s3.amazonaws.com——这会触发验证失败。而本地环境的公共后缀列表可能未将s3.amazonaws.com标记为公共后缀,因此验证通过。

  • DNS解析不一致:生产环境的DNS服务器可能返回了异常解析结果,将foo.s3.amazonaws.com指向了非标准S3节点的IP,该节点的证书虽然包含*.s3.amazonaws.com,但受公共后缀规则影响无法通过验证;本地则解析到正常S3节点,验证无问题。

  • 代理/网关的证书拦截:生产环境存在的代理或网关设备可能对HTTPS请求做了证书重签名,生成的新证书SAN仅包含*.s3.amazonaws.com和s3.amazonaws.com,结合公共后缀的判断逻辑,导致通配符无法匹配目标域名。

  • 类加载或版本差异:生产环境可能存在类加载冲突,实际生效的HttpClient类版本与本地的4.5.13不一致,其DefaultHostnameVerifier的通配符验证逻辑更严格,导致验证失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:14:55