Cas asked me to give a bit of brain dump on SSL as I use it in Danger Maze, so I thought the Networking topic seemed a more appropriate place for it.
I’m going to assume you know how to set up a web server using SSL. Read up on your apache docs if not, or whatever web server you happen to be using. Personally, I’m using Apache 2 on a RedHat Linux server, and found the book “Official RedHat Linux Administrator’s Guide” has an excellent section in the web server chapter about setting up SSL.
Now then, presuiming you want to make a connection from a java client to your SSL web server, here we go. We’re going to use a java.net.URLConnection object, just like you would to make a get/post request over regular http. But we’re going to override the Trust Manager for that connection. So first thing is, we need a TrustManager class.
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
class MyTrustManager extends X509TrustManager {
protected static X509Certificate kCert;
static {
FileInputStream fis = new FileInputStream("mycert.cer");
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
kCert = (X509Certificate)cf.generateCertificate(bis);
}
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException
{
for (int i=0;i<certs.length;i++) {
if (!kCert.equals(certs[i])) {
throw new CertificateException("Certificate does not match!");
}
}
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
You can see I punted on checkClientTrusted and getAcceptedIssuers. I’m only interested in making a connection to a known server, so these methods aren’t really important to me.
Now, to make the request, it should look like this:
SSLContext sc = SSLContext.getInstance("SSL");
TrustManager[] trustManagers = new TrustManager[1];
trustManager[0] = new MyTrustManager();
sc.init(null, trustManagers, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL("https://myserver.com/myservice");
URLConnection conn = url.openConnection();
From there you just use the normal means of creating a post or get with the URLConnection object. One other trick I’ll mention that I’ve done is rather than loading the certificate from a file, you can embed it right into your java class. Simply make a String variable that has the PEM encoded version of your cert, then create an ByteInputStream around the string.getBytes(). Use this instead of the BufferedInputStream above, and you’re all set.
Hope this helps.
–Paul