0

I'm using eclipse and while trying to execute this function I'm getting below error.

I want to send a GET request along with certificate and key. I can download certificate in any format so that's not an issue. I know I need to add this to java keystone but after trying various suggestion I'm still not able to fix this.

   public String sendGET(String GET_URL, String authStringEnc) throws IOException {
            try {
                KeyStore ks = KeyStore.getInstance("JKS");
                FileInputStream fis = new FileInputStream("src/com/resources/ece-cyberark-cert.jks");
                ks.load(fis, "5<@7wBj[Ht()~GRf".toCharArray());
                KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
                kmf.init(ks, "5<@7wBj[Ht()~GRf".toCharArray());
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(kmf.getKeyManagers(), null, null);
                URL obj = new URL(GET_URL);
                HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                if (con instanceof HttpsURLConnection) {
                    ((HttpsURLConnection)con)
                         .setSSLSocketFactory(sc.getSocketFactory());
                }
                con.setRequestMethod("GET");
                con.setRequestProperty("User-Agent", USER_AGENT);
                con.setRequestProperty("Authorization", "Basic " + authStringEnc);      
                con.setRequestProperty("Content-Type", "application/json");
                
                int responseCode = con.getResponseCode();
                System.out.println("GET Response Code :: " + responseCode + " :: " + GET_URL);
                if (responseCode == HttpURLConnection.HTTP_OK) { // success
                    BufferedReader in = new BufferedReader(new InputStreamReader(
                            con.getInputStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();
    
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    con.disconnect();
                    // print result
                    return response.toString();
                } else {
                    // return failed requests response code
                    return "GET request not worked :: GET Response Code :: " + responseCode + " ::  + GET_URL";
                }
            } catch (Exception e) {
                e.printStackTrace();
                return "Exceptionn";
            }
            
            
    
        }

Below is the error -

javax.net.ssl.SSLHandshakeException: 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.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
bosari
  • 1,922
  • 1
  • 19
  • 38
  • 1
    You are initializing your SSL context with a keymanager, but not with a trust manager. The Key manager is usefull if you need to authenticate you (the client) to the server. But here, the issue arises before, when you (the client) try to authenticate the server (your exception shows that). Try getting the server's certificate loaded as a trusted entry inside a keystore that is used to build a TrustManager (second argument of SSLContext#init()). – GPI Jan 08 '21 at 15:17
  • even after adding cert using sudo key tool import I'm still getting same error – bosari Jan 10 '21 at 15:20

1 Answers1

0

Key managers are used to authenticate you, the HTTP client, to the HTTP server. But first, the trust managers are used to authenticate the server. If the server's certificate isn't trusted under the runtime's default "trust anchors", you'll need to provide the correct root certificate explicitly.

KeyStore trusted = ...; /* Initialize a trust store containing the non-standard CA. */
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(trusted);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
...

If you don't intend to use TLS client authentication, you should remove all of the KeyManager related initialization.

erickson
  • 265,237
  • 58
  • 395
  • 493