I am trying to implement SSL using Java RMI, where only the server needs to certificate.
I created my certificate using this guide!
when I run the server and the client using CMD and the following commands
% java -Djavax.net.ssl.keyStore=keystore \
-Djavax.net.ssl.keyStorePassword=password Server
% java -Djavax.net.ssl.trustStore=truststore \
-Djavax.net.ssl.trustStorePassword=trustword Client
everything works great .. but I want to import those commands inside my eclipse project, so what I do is for the server:
super(0, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
System.setProperty("javafx.net.ssl.keyStore","C:\\Users\\Slavi\\workspace\\rmiSSL\\keystore.jks");
System.setProperty("javafx.net.ssl.keyStorePassword","password");
and for the client:
System.setProperty("javafx.net.ssl.trustStore","C:\\Users\\Slavi\\workspace\\rmiSSL\\truststore.jks");
System.setProperty("javafx.net.ssl.trustStorePassword","trustword");
and I get the following errors when the client connects
C:\Users\Slavi\workspace\rmiSSL>java HelloClient
Exception in thread "main" java.rmi.ConnectIOException: error during JRMP connec
tion establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_fai
lure
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unkn
own Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.sayHello(Unknown Source)
at HelloClient.main(HelloClient.java:12)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_
failure
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source
)
at sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source)
at sun.security.ssl.AppOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at java.io.DataOutputStream.flush(Unknown Source)
... 7 more
I think the problem is that the server doesn't set the property at the beggining and using something by default but I have no idea what actually the reason for this is and I am pretty stuck it :(
Any ideas?
EDIT
Server code :
public class HelloImpl extends UnicastRemoteObject implements Hello {
public HelloImpl() throws RemoteException {
super(0, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
System.setProperty("javax.net.ssl.keyStore","C:\\Users\\Slavi\\workspace\\rmiSSL\\keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword","password");
LocateRegistry.createRegistry(3000);
System.out.println("RMI registry running on port 3000");
}
public String sayHello() {
return "Hello World!";
}
public static void main(String args[]) throws Exception {
// Get reference to the RMI registry running on port 3000 in the local host
Registry registry = LocateRegistry.getRegistry(null, 3000);
// Bind this object instance to the name "HelloServer"
HelloImpl obj = new HelloImpl();
registry.bind("HelloServer", obj);
System.out.println("HelloServer bound in registry");
}
and the Client
public class HelloClient {
public static void main(String args[]) throws Exception {
System.setProperty("javax.net.ssl.trustStore","C:\\Users\\Slavi\\workspace\\rmiSSL\\truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword","trustword");
// Get reference to the RMI registry running on port 3000 in the local host
Registry registry = LocateRegistry.getRegistry(null, 3000);
// Lookup the remote reference bound to the name "HelloServer"
Hello obj = (Hello) registry.lookup("HelloServer");
String message = obj.sayHello();
System.out.println(message);
}
javafx.net.ssl.keyStore
That should be
javax.net.ssl.keyStore
Same for the other three.
You need to put these files elsewhere. Your user directory won't be there on the target machines.
And of course you need to set these properties before creating any remote objects that rely on them.