Question

This question is similar to How to use PEM file to create a SSL socket in Java? however I cannot seem to get the suggested solutions working from that question. I used to be able to connect to a .Net Web Service but now they have implemented SLL through certificates, I can no longer access it. The server team have provided me with a cert that will enable me to connect to the Web Service again. And I have confirmed this as working using curl:

curl -E cer_file.pem:password https://hostname/servicename.svc?wsdl

So, the above returns the wsdl correctly. I had to create .cacert.pem file for the curl call to work correctly, to avoid this message (curl: (77) error setting certificate verify locations):

curl http://curl.haxx.se/ca/cacert.pem > .cacert.pem
export SSL_CERT_FILE=/Users/jcran/.cacert.pem

Now when I am trying to use the below Java, I am still getting a 403. I was wondering if anyone can spot what I am doing wrong?

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;


public class TestSSL {

private static final String WS_URL 
    = "https://hostname/servicename.svc?wsdl";
private static final String KS_FILE 
    = "C:/tstfolder/client_side_keystore.jks";
private static final String TS_FILE 
    = "C:/tstfolder/curl_trusted_ca.jks";

public static void main(String... args) throws Exception {
    testConn();
}

public static void testConn() throws Exception {
    System.setProperty("javax.net.ssl.keyStore", KS_FILE);
    System.setProperty("javax.net.ssl.keyStoreType", "jks");
    System.setProperty("javax.net.ssl.keyStorePassword", "importkey");
    System.setProperty("javax.net.ssl.trustStoreType", "jks");
    System.setProperty("javax.net.ssl.trustStore", TS_FILE);
    System.setProperty("javax.net.ssl.trustStorePassword", "password");
    System.setProperty("javax.net.debug", "all");

    SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
    URL url = new URL(WS_URL);
    HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
    conn.setSSLSocketFactory(sslsocketfactory);

    InputStream inputstream = conn.getInputStream();
    InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
    BufferedReader bufferedreader = new BufferedReader(inputstreamreader);


    String string = null;
    while ((string = bufferedreader.readLine()) != null) {
        System.out.println("Received " + string);
    }
}
}

Below are the steps that I used to create the truststore and the keystore. Break the cer_file.pem into a seperate cert.pem and key.pem. Then using the directions at the following link http://www.agentbob.info/agentbob/79-AB.html , I created the client_side_keystore.jks. And then I created the trust store by importing the curl certs file into a jks using the utility found at http://code.google.com/p/java-keyutil/

Unfortunately when I try and read the wsdl through the java test class, I get a 403. Where-as it works through the curl call. I suspect I am doing something silly, or else mis-understanding something. But I was wondering if someone could point me in the right direction?

Was it helpful?

Solution

It sounds like your keystore wasn't converted properly.

It might be easier to build a PKCS#12 file directly from OpenSSL:

openssl pkcs12 -export -in file.crt -inkey file.key -out file.p12

Then, use PKCS12 as the keystore type directly (or convert it to JKS with keytool).

You may want to check that the chain is correct, if there are intermediate certificates, as described here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top