views:

550

answers:

4

I have a Java main application running on my PC that can send XML data to a servelet and recieve XML data back. http://iamt.wisconsin.gov/IAM-WiEntUser/WiEntUserService?xml=

I can use https://iamt.wisconsin.gov/IAM-WiEntUser/WiEntUserService?xml= from IE and Firefox because I they allowed me to load the private certificate.

I want to use https from the Java main application because some of the data is sensitive. I get an IOException with MSG=unkown certificate. Ok, That makes sense, Java does not know about the private certificate.

I was hoping that it would be as simple as telling Java to trust the FireFox certificates. System.setProperty("javax.net.ssl.trustStore", "C:/Documents and Settings/kendajm/Application Data/Mozilla/Firefox/Profiles/6f8ggdi7.default/cert8.db" ); But that gives an IOException with MSG=Invalid keystore format.

SSL communication, how hard can it be? I spent a good eight hours trying to track down how to do this. It seems that is so easy that it is not documented or very difficult and no one has a good example.

Help.

+1  A: 

As I understand it, the problem is that Java will not accept a self-signed certificate. Correct me if I am wrong!

Have you tried using Commons-HttpClient? This has some more options, and on this page there is a guide for accepting self-signed certificates. Also see this sample code

Edit: there is a guide on how to import the certificate into Java here - obviously you will need to do this on each machine that the Java app runs on though. The HttpClient option may be more flexible, depending on what you need.

Phill Sacre
+1; EasySSLProtocolSocketFactory can also be used without Commons-HttpClient.
bwalliser
+1  A: 

I've been able to use a self-signed certificate once I registered it properly with Java using keytool.

See this guide: http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html

Essentially, you: 1. Create a self signed certificate 2. Export it to a file 3. Import it into the default keystore

It is possible that the government website you are trying to integrate with will reject such a self-signed cert, however.

tehblanx
+4  A: 
erickson
A: 
  1. Export the certificate from IE as Base-64 encoded X.509 (.CER)
  2. Run keytool on the exported certificate. Provide trustStore file and password. Reply "yes" to trust question. keytool -import -v -trustcacerts -alias IamtCert -file C:\Work\IAM\Acceptance\IamAcceptanceCertificate.cer -keystore N:\WEB\DEG\CaCert.dat
  3. Add two lines of code. System.setProperty("javax.net.ssl.trustStore","N:\WEB\DEG\CaCert.dat"); System.setProperty("javax.net.ssl.trustStorePassword","xxxxxx");

Not hard once you know what to do. Rest of the code remains the same. (Servlet has another way to valid the caller that does not involve a certificate.)

    urlAddress += encodedXmlData;
    URL  url = null;
    HttpURLConnection connection = null;
 StringBuffer result = new StringBuffer();
    try {
        url = new URL( urlAddress );
        connection = (HttpURLConnection)url.openConnection();
    }
    catch( IOException ioe ) {
        System.out.println(classMethod+": IOException: URL Msg="+ioe.getMessage() );
        return(null);
    }         
    connection.setDoInput(true); // Default value.
 connection.setDoOutput(true); // Not the default value.
 connection.setUseCaches(false); // Not the default value.
 try {
     connection.setRequestMethod("POST");  // Large pay load.
 }
 catch( ProtocolException pe ){
        System.out.println(classMethod+": ProtocolException: URL Msg="+pe.getMessage() );
        return(null);
 }
 // If true, this URL is being examined in a context in which it makes
 // sense to allow user interactions such as popping up an 
 // authentication dialog.
 connection.setAllowUserInteraction(false);
 try {
  connection.connect();
  BufferedReader bufferedReader = new BufferedReader( new
          InputStreamReader( connection.getInputStream() ) );

  // Retrieve the response
        String inputLine = null;
  while ( (inputLine = bufferedReader.readLine() ) != null ) {
      if ( inputLine.indexOf("</void>") > -1 ) inputLine+='\n';
            result.append(inputLine);
  }
  bufferedReader.close();
  connection.disconnect();
 }
 catch( IOException ioe) {
        System.out.println(classMethod+": IOException: Read Msg="+ioe.getMessage() );
        return(null);
 }