【发布时间】:2026-01-01 17:00:01
【问题描述】:
我的想法已经用完了,这就是我在这里寻求帮助的原因。我有一个通过 HTTPS 进行 REST 调用的小类。我正在做某种抓取,并希望尽可能避免安装所有 SSL 证书。
代码在本地运行良好(来自 Eclipse 和独立 Tomcat),但每次从我的 AWS EC2 实例运行时,它都会失败并显示 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure。
代码是:
// apiUrl looks like https://hsreplay.net/api/v1/games/jdUbSjsEcBL5rCT7dgMXRn
private String restGetCall(String apiUrl) throws Exception {
System.setProperty("javax.net.debug", "ALL");
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) {
@Override
protected void prepareSocket(SSLSocket socket) throws IOException {
try {
log.debug("************ setting socket HOST property *************");
PropertyUtils.setProperty(socket, "host", "hsreplay.net");
socket.setEnabledProtocols(new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" });
}
catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
log.error(ex.getMessage());
slackNotifier.notifyError(ex);
}
super.prepareSocket(socket);
}
};
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpGet httpGet = new HttpGet(apiUrl);
CloseableHttpResponse response1 = httpClient.execute(httpGet);
StringBuilder result = new StringBuilder();
try {
System.out.println(response1.getStatusLine());
HttpEntity entity1 = response1.getEntity();
BufferedReader rd = new BufferedReader(new InputStreamReader(entity1.getContent()));
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity1);
}
finally {
response1.close();
}
}
我也尝试了基本版本(没有任何覆盖 SSLFactory 方法),但无济于事。
另外,我无法从 Tomcat 上的 javax.net.debug 获取日志(无论是在远程还是在本地),所以如果您在这里有任何想法,这也可能非常有用。
如果我可以提供更多信息,请告诉我,非常感谢您的帮助!
塞巴斯蒂安
【问题讨论】:
-
你见过this吗?握手失败有许多不同的原因,但是使用最新的信任存储,您似乎应该能够在不安装特定证书的情况下完成这项工作。它似乎是来自 CloudFlare 的 ECC 证书,所以我会说它在服务器端是相对较新的技术,但不在主流之外。
-
@Michael-sqlbot:握手失败(几乎?)从未与服务器证书的验证相关联,因此对信任库的更改将无济于事。
-
@Michael-sqlbot 是的,我已经看到了。我会得出与 Steffen 相同的结论,所以我还没有修改过信任库,但如果我仍然被卡住,可能需要测试一下 :)
-
@SteffenUllrich 谢谢,我正试图解决/解雇“如果可能的话,我想避免安装所有 SSL 证书”,但没有很好地传达我的想法。我打算让这句话表明明确信任(“安装”)服务器的证书作为解决方案的一部分不应该是必要的,除非信任存储是(不太可能的)根本原因,而且我发现它并没有真正出现那样出去。对于不够清晰,我深表歉意。
标签: java ssl amazon-ec2 https