- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试从 Java 8 客户端(使用 Apache HttpClient 4.3)向公共(public)服务器(不属于我)发出 HTTPS 请求。我通常对请求没有任何问题,但目标服务器似乎进行了一些更改并且请求开始失败。
最初,错误是 ValidatorException: PKIX Path Building Failed
但我通过将服务器证书添加到我的 Java 信任库来解决这个问题。我现在得到的错误是 hostname in certificate didn't match: <target.server.com> != <*.something.else.com> OR <something.else.com>
.
something.else.com
主机是某种托管站点等。无论如何我很满意没有任何可疑的事情发生。我为 target.server.com
提取了证书通过运行以下命令:
openssl s_client -connect target.server.com:443 -showcerts
我没有看到任何对 target.server.com
的引用在证书信息中,仅适用于 something.else.com
.我访问 target.server.com
没有任何问题在网络浏览器 (Chrome) 中,没有关于 SSL 证书的投诉。我使用以下命令将服务器证书添加到我的信任库:
sudo keytool -import -file /tmp/target.cer -keystore /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts -alias targetserv
有什么方法可以在不更改 Java 代码的情况下解决这个问题,例如在证书导入命令等中添加一些内容,如果没有,我还能如何让这些请求再次工作。
这是我的 HTTP 请求代码(使用 HttpClient 4.3):
CloseableHttpClient httpClient = HttpClients.custom().setUserAgent(HTTP_USER_AGENT).build();
HttpGet request = new HttpGet(url);
HttpResponse response = httpClient.execute(request);
...抛出 java.io.IOException: hostname in certificate didn't match
此外,这是我试图到达的实际目标服务器:https://www.isi.gov.ie
我已经尝试使用 HttpClient v4.5,但仍然遇到与 4.3 相同的错误。我尝试使用 Java 内置的 HTTP 请求类发出请求,请求成功(返回 302):
URL obj = new URL("https://www.isi.gov.ie");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
有什么方法可以解决 HttpClient 的这些问题吗?
事实证明,在我的应用程序的其他地方,我一直在使用 Java 系统属性 jsse.enableSNIExtension
禁用 SNI我已经忘记了。我这样做的原因是因为这是我能找到的唯一修复方法,可以防止所有使用 HttpClient 的 HTTP 请求因错误而失败:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
如何在不出现这些错误的情况下重新启用 SNI?
我正在使用以下版本的 Java:
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-0ubuntu1.18.04.1-b03)
OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)
最佳答案
TLDR:它可能是 SNI(和链)
显然,与今天的许多服务器一样,该服务器使用 TLS 扩展支持具有不同证书的多个“虚拟”主机 'Server Name Indication'又名 SNI。如果使用 www.isi.gov.ie
的 SNI 进行联系,它会提供对该域和 isi.gov.ie
有效的证书,但如果不使用 SNI 进行联系,它为域 *.rdccremote.ie
和 rdccremote.ie
提供一个过期证书;我认为那些就是您所说的“托管站点”,尽管我没有看到任何迹象;我最好的谷歌搜索结果是 this parliamentary question这似乎权威地说它在政府部门的“共享服务”上——尽管它不使用我可以轻松访问的 DNS 解析到相同的地址 (146.0.55.149)。
此外,这两种证书均由 DigiCert 颁发,但在这两种情况下,服务器都不会按照 TLS 规范要求发送验证所需的链/中间证书。浏览器通常可以“填充”缺失的链证书,但 Java JSSE(和大多数其他软件工具)不能;这可能导致您的路径构建错误,但不会影响主机名不匹配。
openssl s_client
在 1.1.0 以下的版本 默认情况下不发送 SNI,并且您的编辑命令并不表示您为其指定了选项。 (-showcerts
在服务器上比不发送链证书更没用)。还要注意 s_client
仅以解码形式显示证书的主题字段(和 Issuer,分别为 s:
和 i:
),但是不是 SubjectAlt[ernative]Name aka SAN 扩展名,它自本世纪初以来就用于 SSL/TLS 服务器证书的主机名。要查看 SAN,请通过 openssl x509 -text -noout
或其他解码工具(如 keytool -printcert -file $pemfile
)从 s_client
提供 PEM block > 或 Windows 上的证书查看器。
Java 8 通常会发送 SNI,尽管这可能会受到调用代码(应用程序或中间件)的影响。 AHC 4.3 已经很老了,我不确定,但是 4.5 适用于我 Java 7 和 8(Oracle,但 AFAIK JSSE 在 Oracle 和 OpenJDK 之间是相同的)。您(或任何人)能否通过 sysprop jsse.enableSNIExtension=false
配置您的 JVM 以阻止 SNI?您能否使用 sysprop javax.net.debug=ssl
运行并捕获或记录(大)输出,或者使用 wireshark、tcpdump 或类似工具捕获并检查线路数据,以验证您的 Java实际上是在发送 ClientHello 吗?
关于Java HTTPS 请求 : hostname in certificate doesn't match,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56774500/
无法启动 hostname.service:单元 hostname.service 被屏蔽。 这发生在主机名更新之后,尝试执行 sudo 服务主机名启动。 最佳答案 在运行 service hostn
我基于vmware搭建hadoop集群,使用sbin/start-dfs.sh命令,遇到ssh问题。它说, ssh: Could not resolve hostname now.: No addre
我在两个 AWS EC2 实例上运行的集群环境中运行 Airflow。一份给主人,一份给 worker 。工作节点在运行“$airflow worker”时会定期抛出此错误: [2018-08-09
我现在正在设置新的 SuSE Linux Enterprise 12 服务器。有人可以解释一下,/etc/hostname 和 yast2 > 主机名之间有什么区别?两者似乎都有不同的内容,一个地方的
我正在尝试使用 Go SDK 将文件上传到 Amazon S3 存储桶到自定义终端节点,但我收到了该错误: RequestError: send request failed caused by: P
从 cloud.mongodb 处理 URI 后,我尝试通过 compass 进行连接(1.15.1) 在 Windows 10 上,但我收到这个奇怪的错误: No hostname or hostn
我尝试部署了一个测试hadoop集群环境。当我启动它时,所有日志都正确,但是无法运行任何hadoop命令,我发现9000端口没有被监听。 运行hadoop命令(ERROR,所有命令都是一样的错误):
在 Linux 上启动为 Apache Solr 4.x 配置的 tomcat6 服务时,如果有人可以帮助解决在 catalina.out 中记录的这个问题,我将不胜感激: Mar 22, 2014
我有一个本地网络,上面有几台 PC 和专用 Controller 。这些专用 Controller 必须配置静态 IP 地址,并且不具备 DHCP 功能。 我被要求将设备主机名和 IP 地址的列表放在
我正在使用 puppet 来配置服务器。我想在 *.erb 模板中打印当前机器(节点)名称。有主机名变量,但这包含 puppetmaster 主机名。是否有关于此主题的任何好的引用/列表? 最佳答案
我对这些概念 super 陌生,如果这很愚蠢,我深表歉意。我正在尝试使用Elasticsearch数据源在Grafana上可视化Metricbeat数据,这些数据源均在本地运行,但无法找到Metric
假设我有一个具有以下属性的虚拟机 FQDN :trialinstance.westus.cloudapp.azure.com Public IP : XXX.XXX.XXX.XXX Private I
假设我有一个具有以下属性的虚拟机 FQDN :trialinstance.westus.cloudapp.azure.com Public IP : XXX.XXX.XXX.XXX Private I
在 CLI Linux 中我运行: echo $HOSTNAME 并接收: alex-HP-295-G1-SFF-Business-PC 我尝试在java中获取这个环境 ExpressionPa
如果我回显一个包含 $(hostname) 命令的字符串,那么它工作正常。例如,在终端中运行: echo "http://$(hostname)/main.html" http://artur/mai
我想写一个C++代码来获取所有主机名的完整信息,以及已添加到域控制的计算机的IP地址和子网掩码。 最佳答案 gethostname 会给你当前主机的名字 gethostbyname 查找具有特定名称的
在 CLI 模式下 getenv('HOSTNAME') 正确返回 HOSTNAME 环境变量,但在脚本中调用时返回 FALSE。 为什么?如何在脚本中获取 HOSTNAME 变量? 最佳答案 HOS
本文是关于Linux操作系统主机名(hostname)的文档,对主要配置文件/etc/hosts进行简要的说明 ;另外对基配具工具hostname也进行了举例说明; 欢迎高手斧正,谢谢; 目录
需要修改两处:一处是/etc/sysconfig/network,另一处是/etc/hosts,只修改任一处会导致系统启动异常。首先切换到root用户。 复制代码
使用Win7,Gitolite和TortoiseGIT 今天,我将GIT更新为2.6.1版,因此必须卸载旧版本。 很久以前,我创建了一个ssh-config文件,以更轻松地访问我的存储库,并且从今天开
我是一名优秀的程序员,十分优秀!