0

I'm using the Java RMI to send objects from a Client -> to a Server. Primitive objects works fine(e.g. String etc.) Java objects from the crypto library, throws exception. I need these Java Objects to settle on a secret key in a DiffieHellman Key Exchange Exception here:

Exception in thread "main" java.rmi.MarshalException: error marshalling arguments; nested exception is: 
    java.io.NotSerializableException: javax.crypto.spec.DHParameterSpec
    at sun.rmi.server.UnicastRef.invoke(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
    at com.sun.proxy.$Proxy0.DiffieExchange(Unknown Source)
    at rmihello.Client.main(Client.java:51)
Caused by: java.io.NotSerializableException: javax.crypto.spec.DHParameterSpec
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at sun.rmi.server.UnicastRef.marshalValue(Unknown Source)
    ... 5 more

Code

//The Client
public class Client {
    public static void main(String[] args) throws Exception {
        HelloService lookup = (HelloService) Naming.lookup("rmi://localhost:5099/hello");
        //Some crypto stuff
        String username = console.next();
        BigInteger p1024 = BigInteger.probablePrime(1024, new SecureRandom());
        BigInteger g = BigInteger.valueOf(2);
        DHParameterSpec dhParams = new DHParameterSpec(p1024,g);
        //A Module I have that generates KeyPairs
        KeyPair kp = DiffieHellmanModule.genDHKeyPair(dhParams); 
        PublicKey clientPubKey = kp.getPublic();
        //@@@@@@@--FAILS--@@@@@@@
        PublicKey serverPubKey = lookup.DiffieExchange(clientPubKey,dhParams,username);
    }
}

//The interface for RMI
public interface HelloService extends Remote{
    public PublicKey DiffieExchange(PublicKey clientPublicKey, 
              DHParameterSpec dhParams,String username) throws RemoteException;
}
//The server servant implementing the interface for RMI
public class HelloServant extends UnicastRemoteObject implements HelloService{

    protected HelloServant() throws RemoteException {
        super();
    }

    @Override
    public PublicKey DiffieExchange(PublicKey clientPublicKey,
            DHParameterSpec dhParams, String username) throws RemoteException {
        KeyPair key = DiffieHellmanModule.genDHKeyPair(dhParams);
        PublicKey serverPubKey = key.getPublic();
        return serverPubKey;
    }
}
//The Application server
public class ApplicationServer {
    public static void main(String[] args) throws RemoteException, AlreadyBoundException {
        Registry registry = LocateRegistry.createRegistry(5099);
        registry.rebind("hello", new HelloServant());
    }
}
user3711518
  • 253
  • 1
  • 3
  • 14
  • 1
    I'm not sure if there's a way to solve this – some classes just don't support serialization. – ntoskrnl Nov 09 '14 at 21:44
  • 1
    Exactly so. If they're not Serializable you can't use them in remote methods. You may however be able to get them as bytes, send the bytes, and reconstitute them from the bytes at the receiver. Have a look at the APIs for the crypto objects of interest. They mostly have `getEndoded()` methods, and factories or constructors that can build them from byte arrays. – user207421 Nov 09 '14 at 22:30

1 Answers1

1

If they're not Serializable, you can't use them in remote methods.

You may however be able to get them as bytes, send the bytes, and reconstitute them from the bytes at the receiver. Have a look at the APIs for the crypto objects of interest. Crypto objects in Java mostly have getEncoded() methods, and factories or constructors that can build them from byte arrays.

user207421
  • 305,947
  • 44
  • 307
  • 483