【发布时间】:2020-09-12 23:06:10
【问题描述】:
我无法向在浏览器中正常工作的第 3 方 https URL 发送简单的 GET 请求:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://...": Received fatal alert: handshake_failure; nested exception is javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:673)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:635)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:556)
我尝试关注related answers,但没有找到解决方案。
没有证书,我使用的是 Java 8,尝试了添加-Djsse.enableSNIExtension=false -Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1的解决方案
添加了与浏览器发送相同的标题(Accept 和 User-Agent),但没有运气
代码
UriBuilder uriBuilder = UriBuilder.fromUri(URLDecoder.decode(URL, "UTF-8"));
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", "text/html,application/xhtml+xml,application/xml");
headers.add(HttpHeaders.USER_AGENT, "Mozilla...");
HttpEntity<?> entity = new HttpEntity<Object>(headers);
ResponseEntity<ResponseVO> response = restTemplate.exchange(uriBuilder.build(),
HttpMethod.GET, entity, ResponseVO.class);
- 网站使用 cloudflare 服务
curl 也通过输入完整的 url 来工作,从详细的输出中它使用服务器证书:
SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
也尝试了配置 skip SSL certificate verification 并具有相同的输出:
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom() .loadTrustMaterial(null, 接受TrustStrategy) .build();
或者也可以使用NoopHostnameVerifier:
CloseableHttpClient httpClient = HttpClients.custom() .setSSLHostnameVerifier(新 NoopHostnameVerifier()) 。建造(); HttpComponentsClientHttpRequestFactory requestFactory = 新的 HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient);
curl -v 结果服务器证书:
* subject: CN=*.site.com,OU=Domain Control Validated
* start date: May 24 08:13:23 2019 GMT
* expire date: May 24 08:13:23 2021 GMT
* common name: *.site.com
* issuer: CN=Go Daddy Secure Certificate Authority - G2,OU=http://certs.godaddy.com/repository/,O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US
编辑
我将证书添加到 java 为 @Walk suggested:
sudo keytool -importcert -file filename.cer -alias randomaliasname -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
证书已添加到密钥库
我看到证书在浏览器中加载,它在 JMeter 中工作,但使用 restTemplate 或 apache HTTPClient 仍然失败并出现同样的错误。
我正在使用 Java 8 更新 151。
尝试@rmunge 回答中的solution 添加BouncyCastleProvider,但仍然出现同样的错误
security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider
【问题讨论】:
-
你可以使用 cURL 或类似的方法来请求吗?也许你的浏览器有一个与 Java 或类似的不同的信任库。
-
@Smutje curl 通过放置完整的网址来工作
-
是否启用了证书检查?
-
@Nish 它也发生在默认的restTemplate为
new RestTemplate() -
我相信@Smutje 可能是对的。也许您的 java 信任库没有服务器 CA 证书,您可以尝试将其添加到您的 java 信任库中,这将是我的第一次尝试。
标签: java java-8 httpclient resttemplate handshake