1

When I try to connect to https website like follows:

StringBuilder sb = new StringBuilder();
        URL oracle = new URL("https://company.com");
        URLConnection yc = oracle.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null)
            sb.append(inputLine);
        in.close();
        return sb.toString();

I get

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)

If I use the http://company.com instead it works but I want to use the https one because that is what they say to use and I think the non secure one may be removed.

However when i have looked at similar answers about this it talks about copying certificates from my browser ectera. I need a solution that will work for anyone running the code on any computer without having to do anything special.

Im not concerned about the security advantages of SSL for this project I just want to be able to connect to the wenbsite.

Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
  • 3
    By "not worrying about" SSL, you're saying that you don't care of your program is fooled by man-in-the-middle attacks, even though the site in question clearly *does* care about man-in-the-middle attacks (if they say to use the https version and that the http version may be removed at some point). – T.J. Crowder Feb 14 '17 at 15:19
  • First, if the site does not offer HTTP then you'll fail anyway. Second, your request should work as the runtime comes with a default [trust store](http://stackoverflow.com/questions/1398556/connect-to-https-siteserver). Maybe the certificate on that website has issues and can't be validated. – Alfabravo Feb 14 '17 at 15:21
  • @T.J.Crowder look if they didnt provide a https version you wouldnt be telling me not to use the site, there is nothing critical/sensitive about the data. So instead of criticising me for not being concerned about ssl in thsi cirumstance how do I solve the issue – Paul Taylor Feb 14 '17 at 15:26
  • @Alfabravo i dont understand your point, they do currently support http. My request doesnt work although everything else does so how can I fix so it works for me and every other user on whatever computer they are using – Paul Taylor Feb 14 '17 at 15:27
  • Check in a standard browser if the certificate is valid, was issued by a trusted CA and so on. If the browser reports any issue, you'll confirm that the problem is not with your request but with the certificate. In that case, you'll need to add the issuer as a trusted CA in the trust store. – Alfabravo Feb 14 '17 at 15:29
  • 2
    @PaulTaylor: That's the point, which I made above: If the site expects and -- you've suggested -- may soon *require* you to use https to access it, they presumably *have a reason for that*. If they didn't, they could just use http and you wouldn't have this problem. If you ask "How can I open this locked door without the key" and someone says "Well, maybe trying to get past it without the key isn't a good idea" and you say "But if it weren't locked you wouldn't tell me that" makes no sense. Anyway, I leave you to it, and good luck. – T.J. Crowder Feb 14 '17 at 15:30
  • @T.J.Crowder their reason is simply 'ssl is more secure' but why should there reason be a good reason for me as end user, for example I considered making my own website ssl purely because Google gives https sites a small ranking boost but it would have been of no help to users of my site ! Your analogy is incorrect not asking how to bypass their lock I'm simply saying i don't need the extra protetcion ssl could theoretically provide.But regardless of this I dont udnerstand how to make it work whether I 'do it properly' or not. – Paul Taylor Feb 14 '17 at 15:43
  • @Alfabravo i don't see how to check, but no error when open in firefox browser, this is actual url https://acousticbrainz.org/api/v1/96685213-a25c-4678-9a13-abd9ec81cf35/low-level – Paul Taylor Feb 14 '17 at 15:46
  • I just ran your code with the URL provided and worked as expected (prints the JSON with all the data). What version of Java are you using? Also, please check if the answer to [this question](http://stackoverflow.com/questions/9619030/resolving-javax-net-ssl-sslhandshakeexception-sun-security-validator-validatore#9619478) is relevant. – Alfabravo Feb 14 '17 at 17:30

1 Answers1

1

It seems you've already been warned against the approach, so I'll stick to answering your question. I was able to reproduce the problem on my machine, although I can't tell why: My browser accepts the site's certificate without a hitch.

I've tried expanding on your code to make it work, but soon found myself messing with SSLContext, various crypto-providers and service provider interfaces. I didn't manage to complete this approach, and wouldn't actually recommend going that way, as it changes the global security settings of your JVM and may have unpredictable consequences depending on what else it's doing.

Instead I suggest you take a look at the Apache HttpComponents library, which allows for more fine-grained control of the connection's security settings.

The following will disable all certificate validation for the created HttpClient instance:

TrustStrategy veryNaive = new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return true;
    }
};

SSLContext sslcontext = SSLContexts.custom()
    .loadTrustMaterial(veryNaive)
    .build();

CloseableHttpClient httpclient = HttpClients.custom()
    .setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext))
    .build();

try {
    HttpGet httpget = new HttpGet("https://company.com");

    try (CloseableHttpResponse response = httpclient.execute(httpget);) {
        HttpEntity entity = response.getEntity();
        System.out.println(EntityUtils.toString(entity));
        EntityUtils.consume(entity);
    }
} finally {
    httpclient.close();
}

Changing the SSLContext to SSLContexts.createSystemDefault(); re-introduces the problem, just to demonstrate that it's also present for the Apache library.

Henrik Aasted Sørensen
  • 6,966
  • 11
  • 51
  • 60
  • thankyou so much for the solution, I have one issue though I am using HttpComponents 4.5.3 and SSLContexts.custom().loadTrustMaterial() seems to require a truststore rather than a truststrategy ? – Paul Taylor Feb 15 '17 at 09:33
  • @PaulTaylor: Check that you're using the correct one. The library seems to contain two `SSLContexts` classes, one of which is deprecated. The correct one is `org.apache.http.ssl.SSLContexts` (http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/ssl/SSLContexts.html). – Henrik Aasted Sørensen Feb 15 '17 at 09:37
  • thankyou that works. My only problem now is that sometimes the url I lookup does not exist and your code doesnt quite handle that as it returns some json indicating not found rather than returning nothing/ giving an error code whihc is different to my http (no-secure) case. – Paul Taylor Feb 15 '17 at 10:13
  • Fixed now, added int statusCode response.getStatusLine().getStatusCode();if(statusCode!=HttpURLConnection.HTTP_OK) return ""; – Paul Taylor Feb 15 '17 at 10:31
  • Excellent! Was about the provide you with the javadoc of the `HttpResponse` class, which contains what you needed. (https://static.javadoc.io/org.apache.httpcomponents/httpclient/4.5.3/org/apache/http/client/methods/CloseableHttpResponse.html) – Henrik Aasted Sørensen Feb 15 '17 at 10:32