Aspirant Aspirant - 3 years ago 220
Java Question

How to connect to an HTTPS URL from a JavaFX application

I have a Javafx application that sends GET and POST requests to a secure web service via HTTPS. The SSL setup on the server hosting the webservices is one-way ssl, i.e. the Javafx application validates the server's identity but the server does not validate the thick client's identity.

The application server is behind an F5 that has the certificates(signed by an external authority).

For a browser this would not have been a problem as the browser itself handles validating the server's identity and displays the relevant warning to the user. But for a thick client, I am not sure how to validate the server's identity before sending the request. Please let me know how to handle this in a Javafx application.

I did ask a question relating to this earlier here and here, but those did not help. So, please pardon my limited knowledge on this topic.

Any help would be appreciated.

Answer Source

If your certificate don't work in Firefox/java, most likely it issuer is unknown by Firefox/java.

How to make it work:

  1. Get full certificate chain of your server. You can do it with Firefox. View certificate -> details-> export to .pem file. In your case chain will contain at least 2 certificate (cerver cert and CA cert, CA possible self-signed or maybe not) Export CA certificate in .pem file.

  2. Now you can force java to trust that CA, it can be done in various ways, for example, you can add CA certificate in jre cacerts or create custom SSLContext for HttpsURLConnection.

  3. If you do DNS or etc.hosts modification, rollback it. Connection address should match with certificate CN, include wildcards.

  4. Use that code to connect to your server:

    public void test() throws Exception {
        URL u = new URL(
                "https://my-server.com/my-webservices/data");
        HttpsURLConnection http = (HttpsURLConnection) u.openConnection();
        http.setSSLSocketFactory(createSSLContext().getSocketFactory());
        http.setAllowUserInteraction(true);
        http.setRequestMethod("GET");
        http.connect();
    
        InputStream is = http.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder stringBuilder = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null)
        {
            stringBuilder.append(line
                    + "\n");
        }
        System.out.println(stringBuilder.toString());
    
    }
    
    private SSLContext createSSLContext() throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        FileInputStream in = new FileInputStream("path_to_ca_file.pem");
        KeyStore trustStore = KeyStore.getInstance("JKS");
        trustStore.load(null);
        try {
            X509Certificate cacert = (X509Certificate) cf.generateCertificate(in);
            trustStore.setCertificateEntry("ca", cacert);
        } finally {
            IOUtils.closeQuietly(in);
        }
    
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(trustStore);
    
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
        return sslContext;
    }
    
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download