Friday June 23, 2006 Using the SSL/TLS-based RMI Socket Factories in Java SE 6 with the JNDI/RMI Registry Service Provider
This is a followup of my previous blog entry Using the SSL/TLS-based RMI Socket Factories in J2SE 5.0.
In this new entry I will update the example to show you how SSL/TLS-based connections to the RMI registry are now supported in Mustang (Java SE 6) when using the JNDI/RMI Registry Service Provider.
Let's have a look first at the example using the JNDI/RMI Registry Service Provider but without any SSL/TLS protection at all.
public interface Hello extends Remote {
public String sayHello() throws RemoteException;
}
|
public class HelloImpl extends UnicastRemoteObject implements Hello {
public HelloImpl() throws RemoteException {
super();
}
public String sayHello() {
return "Hello World!";
}
public static void main(String args[]) throws Exception {
// Bind this object instance to the name "HelloServer"
HelloImpl obj = new HelloImpl();
InitialContext ctx = new InitialContext();
ctx.bind("rmi://localhost:3000/HelloServer", obj);
System.out.println("HelloServer bound in registry");
}
}
|
public class HelloClient {
public static void main(String args[]) throws Exception {
// Lookup the remote reference bound to the name "HelloServer"
InitialContext ctx = new InitialContext();
Hello obj = (Hello) ctx.lookup("rmi://localhost:3000/HelloServer");
String message = obj.sayHello();
System.out.println(message);
}
}
|
public class RmiRegistry {
public static void main(String[] args) throws Exception {
// Start RMI registry on port 3000
LocateRegistry.createRegistry(3000);
System.out.println("RMI registry running on port 3000");
// Sleep forever
Thread.sleep(Long.MAX_VALUE);
}
}
|
In order to run the example open a shell window, go to the directory containing the compiled class files and call:
What would happen if the RMI registry had been started with the SSL/TLS-based RMI Socket Factories?
In J2SE 5.0, that would mean HelloImpl and HelloClient would have to access the RMI registry through the getRegistry method as shown in my previous blog entry.
In Mustang, the JNDI/RMI Registry Service Provider defines a new environment property com.sun.jndi.rmi.factory.socket that can be supplied in the InitialContext's Hashtable parameter. This environment property can be set to any socket factory of type RMIClientSocketFactory, i.e. the new environment property can be set to the SslRMIClientSocketFactory.
So let's finally protect the access to the RMI registry with SSL/TLS and modify HelloImpl and HelloClient in the example to let them access the RMI registry through SSL. As stated before, the SSL/TLS-based RMI Socket Factories used to create the RMI registry must require client authentication as this is the only way the RMI registry can refuse requests from clients sending untrusted certificates.
The following files need to be changed as follows:
public class HelloImpl extends UnicastRemoteObject implements Hello {
public HelloImpl() throws RemoteException {
super();
}
public String sayHello() {
return "Hello World!";
}
public static void main(String args[]) throws Exception {
// Bind this object instance to the name "HelloServer"
HelloImpl obj = new HelloImpl();
Hashtable<String,Object> env = new Hashtable<String,Object>();
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
InitialContext ctx = new InitialContext(env);
ctx.bind("rmi://localhost:3000/HelloServer", obj);
System.out.println("HelloServer bound in registry");
}
}
|
public class HelloClient {
public static void main(String args[]) throws Exception {
// Lookup the remote reference bound to the name "HelloServer"
Hashtable<String,Object> env = new Hashtable<String,Object>();
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
InitialContext ctx = new InitialContext(env);
Hello obj = (Hello) ctx.lookup("rmi://localhost:3000/HelloServer");
String message = obj.sayHello();
System.out.println(message);
}
}
|
public class RmiRegistry {
public static void main(String[] args) throws Exception {
// Start RMI registry on port 3000
LocateRegistry.createRegistry(3000,
new SslRMIClientSocketFactory(),
new SslRMIServerSocketFactory(null, null, true));
System.out.println("RMI registry running on port 3000");
// Sleep forever
Thread.sleep(Long.MAX_VALUE);
}
}
|
In order to run the example open a shell window, go to the directory containing the compiled class files and call:
How would this example work if the client running through Web Start?
Anyway, is secure the client use the same keystore used by the server?
Regards,
Eldes
Posted by Eldes on April 22, 2008 at 11:27 PM CEST #