Let\'s say I want to ship a commercial product that has two components, written in Java, communicating with each other on a local network using a RESTful API. It could be a musi
Updated Sep 20 '15 to clarify the points raised in comments
To understand how this can be done, let us examine a possible deployment scenario of such an application. Assume that the application in question comprises two components - the client part and the server part, meant to be installed onto different computers on a local network. We want our server part to accept secure connections only, so the local network is considered hostile.
Install the server part. At the time of the installation, programmatically create a self-signed certificate using the hostname of a target computer. If there is no DNS record for the computer (like myserver.mycorp.com), use its IP address - it has to be static since we need to point the client part to it. You can use Bouncy Castle API to create a certificate in code.
Install the client part onto another computer, and copy the generated certificate to the installation folder. Doing this manually is effectively establishing trust between the server and client. Trying to do this automatically via an unencrypted connection over a hostile network would be defeating the purpose.
Since you are securing communication strictly beetween your own application parts, you are in full control of what certificates the application in question trusts. On the client, create a keystore, and add the generated certificate to it:
FileInputStream fis = new FileInputStream(yourCertificateFile);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate c = (X509Certificate)cf.generateCertificate(fis);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, aRandomKeystorePasswordCharArray);
ks.setCertificateEntry(aUniqueNameForYourCertificate, c);
FileOutputStream fos = new FileOutputStream(aRandomKeystoreFileName);
ks.store(fos, aRandomKeystorePasswordCharArray);
fos.close();
Tell the JVM that your application is only going to trust certificates from its own keystore.
// replace backslashes '\' with slashes '/' in aRandomKeystoreFileName on Windows
System.setProperty("javax.net.ssl.trustStore", aRandomKeystoreFileName);
System.setProperty("javax.net.ssl.trustStorePassword", aRandomKeystorePassword);