I'm failing to send simple GET request to 3rd party https URL which works fine in browser:
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)
I try follow related answers, but I didn't find solution.
There's no certificate and I'm using Java 8, tried solutions as adding -Djsse.enableSNIExtension=false -Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1
Added same headers as browser sends (Accept
and User-Agent
) , but no luck
Code
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);
- Site uses cloudflare services
Also curl is working by putting full url, from verbose output it uses Server certificate with:
SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Tried also with configuration skip SSL certificate verification with same output:
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom() .loadTrustMaterial(null, acceptingTrustStrategy) .build();
Or also with NoopHostnameVerifier:
CloseableHttpClient httpClient = HttpClients.custom() .setSSLHostnameVerifier(new NoopHostnameVerifier()) .build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient);
curl -v results Server certificate:
* 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
EDIT
I added certificate to java as @Walk suggested:
sudo keytool -importcert -file filename.cer -alias randomaliasname -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
Certificate was added to keystore
I see certificate loaded as in browser, it works in JMeter, but still failed with same error using restTemplate or apache HTTPClient.
I'm using Java 8 update 151.
Tried solution from @rmunge answer to add BouncyCastleProvider, but still same error
security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider
new RestTemplate()
– user7294900