Skip to content

Instantly share code, notes, and snippets.

@rjoffray
Created February 15, 2023 22:39
Show Gist options
  • Save rjoffray/829ca118c1df469e407404a2b9cea50b to your computer and use it in GitHub Desktop.
Save rjoffray/829ca118c1df469e407404a2b9cea50b to your computer and use it in GitHub Desktop.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
public class RMIClient {
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.ssl.keyStore", "client-keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("javax.net.ssl.trustStore", "client-truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(RMIClient.class.getResourceAsStream("client-keystore.jks"), "password".toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(RMIClient.class.getResourceAsStream("client-truststore.jks"), "password".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "password".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
RMIInterface stub = (RMIInterface) registry.lookup("RMIInterface");
System.out.println(stub.sayHello());
}
}

Here, we're setting some system properties related to TLS, loading our client key and trust stores, and creating a new SSLContext object. We're then creating a registry at port 1099, looking up the RMIServer object under the name "RMIInterface", and calling its sayHello() method.

Both the client and server code require the RMIInterface interface, which is defined as follows:

This interface defines the sayHello() method, which is implemented by the RMIServer class.

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIInterface extends Remote {
public String sayHello() throws RemoteException;
}
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
public class RMIServer implements RMIInterface {
public RMIServer() {}
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.ssl.keyStore", "server-keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("javax.net.ssl.trustStore", "server-truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(RMIServer.class.getResourceAsStream("server-keystore.jks"), "password".toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(RMIServer.class.getResourceAsStream("server-truststore.jks"), "password".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "password".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
// Export the RMI object
RMIInterface stub = (RMIInterface) UnicastRemoteObject.exportObject(new RMIServer(), 0);
// Bind the object to the registry
Registry registry = LocateRegistry.createRegistry(1099);
registry.bind("RMIInterface", stub);
System.out.println("RMIServer is running...");
}
public String sayHello() throws RemoteException {
return "Hello from RMIServer!";
}
}

This server code loads the server's key and trust stores and creates an SSLContext object, similar to the client code. It then exports the RMIServer object using the UnicastRemoteObject.exportObject() method and binds the object to the registry with the name "RMIInterface".

When a client connects to this server, it will authenticate itself using the server's trust store and present its own certificate to the server, which will authenticate the client using the client's certificate.

Note that the RMIInterface interface is also required by the server, as it defines the sayHello() method that the server implements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment