【发布时间】:2015-01-06 03:36:20
【问题描述】:
我正在使用 Java RMI 将对象从客户端 -> 发送到服务器。 原始对象工作正常(例如字符串等) 来自加密库的 Java 对象引发异常。 我需要这些 Java 对象来确定 DiffieHellman 密钥交换中的密钥 这里的例外:
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
代码
//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());
}
}
【问题讨论】:
-
我不确定是否有办法解决这个问题——有些类就是不支持序列化。
-
正是如此。如果它们不可序列化,则不能在远程方法中使用它们。但是,您可以将它们作为字节获取,发送字节,并从接收器的字节中重构它们。查看感兴趣的加密对象的 API。它们大多具有
getEndoded()方法,以及可以从字节数组构建它们的工厂或构造函数。
标签: java serialization cryptography rmi object-serialization