0

I am trying to connect to a Rest API, and the code is as below,

    public class TestingDevelop {
    
        public static String fetchAccessToken(){
            HttpClient httpclient = new DefaultHttpClient();
            String client_id ="clientID";
            String client_secret ="clientSecret";
            String grant_type="client_credentials";
            String accessTokenUrl = "tokenURL";
            String scope = "scope";
            HttpPost post = new HttpPost(accessTokenUrl);
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("client_id",client_id ));
            params.add(new BasicNameValuePair("client_secret", client_secret));
            params.add(new BasicNameValuePair("grant_type", grant_type));
            params.add(new BasicNameValuePair("scope", scope));
            post.setEntity(new UrlEncodedFormEntity(params));
            System.out.println(post);
            HttpResponse response = httpclient.execute(post);
            String body = EntityUtils.toString(response.getEntity());
            //the response is a json response and I am fetching the token from this.    
            return token;
        }
    
    }

I have used the generated token in postman and have checked, it works fine as expected.

Now, when I try to call the GET api, it throws

javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Get API code:

private static void useBearerToken(String bearerToken) {
            BufferedReader reader = null;
            try {
                
                String restApiUrl ="https://api.byu.edu:443/echo/v1/status?test=testing";
                URL url = new URL(restApiUrl);
                HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                connection.setRequestProperty("Authorization", "Bearer " + bearerToken);
                connection.setDoOutput(true);
                connection.setRequestMethod("GET");
                reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line = null;
                StringWriter out = new StringWriter(connection.getContentLength() > 0 ? connection.getContentLength() : 2048);
                while ((line = reader.readLine()) != null) {
                    out.append(line);
                }
                String response = out.toString();
                System.out.println(response);
            } catch (Exception e) {

            }
    
    }

When, I look at the configuration at the postman side, the SSL is disabled.

enter image description here

I have seen similar question being asked but it did not work for me. Here are some of the links which I have gone through:

  1. Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?
  2. Tried disabling the cert validation: SSLHandshakeException: ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
  3. PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException java

Updates

Postman console log:

tls: {…}
reused: false
authorized: false
authorizationError: "UNABLE_TO_VERIFY_LEAF_SIGNATURE"

Setting self signed certificate:

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048

setting system properties:

System.setProperty("javax.net.ssl.trustStore", "keystore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "password");

and setting SSLContext

 SSLContext.setDefault(
 createSSLContext("/keystore.jks", "password"));
 

// call fetchAccessToken and useBearerToken()

The call fails before going to fetchAccessToken method.

User27854
  • 824
  • 1
  • 16
  • 40
  • Was that site was using a self signed certificate? – Abimaran Kugathasan Apr 26 '22 at 02:26
  • I am not sure. We were accessing it using Postman, and I was able to get proper response. As put in the screenshot, the SSL was disabled. Even on checking the console log at the postman, I can observe that the Authentication is disabled. ConsoleLog, is update in the question. – User27854 Apr 26 '22 at 02:31
  • @AbimaranKugathasan, Assuming that they are using self signed certificate, how should, I handle it? – User27854 Apr 26 '22 at 02:38
  • You may refer this https://stackoverflow.com/questions/6908948/java-sun-security-provider-certpath-suncertpathbuilderexception-unable-to-find – Abimaran Kugathasan Apr 26 '22 at 02:40
  • @AbimaranKugathasan, let me try that. Just curious, In that case how is postman handling it? – User27854 Apr 26 '22 at 02:44
  • your postman turned the verification off, which means it would bypass the handshake failure and always establish the connection – Hưng Chu Apr 26 '22 at 02:53
  • Your configuration doesn't show 'SSL is disabled' and in fact it isn't; only _verification of the certificate_ is disabled. That means postman ignores the fact the certificate is invalid and proceeds with the connection anyway, which is why you get a response -- which could actually be from any criminal in the world, not the server you want, and could be fake, fraudulent, malicious, and harmful. However, api.byu.edu does NOT use a self-signed cert @AbimaranKugathasan; its cert is from DigiCert, with a valid chain, and validates fine on my system's several versions of Java. ... – dave_thompson_085 Apr 26 '22 at 03:14
  • ... 27854: what java are you running and how was it installed -- on Linux from which distro repository, from www.oracle.com, something else? Has that installation been modified? Do you set sysprops `javax.net.ssl.trustStore*` to override the default? Does anything running in your JVM alter the default SSLContext, SSLFactory, or truststore? Are you in an environment where network requests are 'inspected', like a business, school, or motel etc? Try `keytool -printcert -sslserver api.byu.edu` and see if you get a cert #0 with `Issuer: CN=DigiCert TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US`. – dave_thompson_085 Apr 26 '22 at 03:18
  • @dave_thompson_085, I am running on a Mac os. My java version is Open JDK 11.0.12+0. I have installed it using HomeBrew, On installation, I have not modified any anything. I have not set the SSL trustStore. No software are altering SSL Context or truststore. No, there is not network restriction. I have no certs currently. – User27854 Apr 26 '22 at 03:46
  • @dave_thompson_085, I have run this command and have created a selfsigned certificate. keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048. – User27854 Apr 26 '22 at 03:47
  • @AbimaranKugathasan, I have created a self signed certificate and have added set the system properties. Now it throws No X509TrustManagerImplementation. I have updated the question. – User27854 Apr 26 '22 at 03:59
  • (0) Add this info to the Q where others will see it. I don't know what homebrew uses for Java truststore, but if you know/find where it puts the JRE, `keytool -list -keystore JRE/lib/security/cacerts` and see what's in there (1) creating your own cert and using it as the only trusted 'CA' can never work, because neither api.byu.edu nor anybody else in the world does or ever will use a cert issued by yours (2) you created the file with password p-a-s-s-w-o-r-d but tried to access it using p-a-s-s-w-o-r-d-space which is different and wrong – dave_thompson_085 Apr 26 '22 at 06:09
  • @dave_thompson_085, I have specified the password correctly. The typo occurred while copying the code to stack overflow. – User27854 Apr 26 '22 at 07:18

0 Answers0