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);
Have a look at comparison between Facebook Connect, OAuth and OpenID at TheNextWeb
OpenID: OpenID serves as the third party that can verify who you are
OAuth: A safer and more secure way for people to give you access
Facebook Connect: With Facebook Connect, what we see are elements of both OpenID and OAuth. Facebook Connect can verify that you are who you say you are, and it can then provide access to your data once you’ve given it permission to do so.
Summary:
OpenID and OAuth think that they have a collective right answer, but Facebook clearly thinks that it has its own. We have to see how it shapes up in future.
Look to OAuth 2.0 for securing your services and you should only provide tokens to your clients instead of two way SSL. Facebook,Google etc. uses it.
https://en.wikipedia.org/wiki/OAuth
Your linked answer presents another solution: instead of disabling certificate validation for self-signed certificates, 'Export the certificate (...) and import it in your JVM truststore'.
So only for the first time when an unknown certificate is found, ask for user confirmation.