In this project I have a KeyPairCreator that generate 2 asymetric key pair and serialized it into a file and a KeyDistrCenter that generate DES keys.
My SecureSocketFactory and SecureServerSocketFactory communicate with KeyDistrCenter using Public/Private key pair and recieve from it
the encrypted secret DES key. Then, the "factories" decrypt the secret key and inizialize my special socket (class NewSecureSocket) . The Public/Private key used are those realized from KeyPairCreator
so, for proving the program, you have launch first KeyPairCreator then KeyDistrCenter and finally HelloImpl (bind operation) and HelloC (lookup operation)
the exception is:
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested excepti
on is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185
)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Remo
teObjectInvocationHandler.java:179)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvo
cationHandler.java:132)
at $Proxy0.sayHello(Unknown Source)
at HelloC.main(HelloC.java:9)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:507)
at java.net.Socket.connect(Socket.java:457)
at java.net.Socket.<init>(Socket.java:365)
at java.net.Socket.<init>(Socket.java:178)
at NewSecureSocket.<init>(NewSecureSocket.java:22)
at SecureSocketFactory.createSocket(SecureSocketFactory.java:27)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569)
... 7 more
the code is:
public class SecureStreamFactory {
private static SecureStreamFactory theSecureStreamFactory;
private SecureStreamFactory() {}
public static SecureStreamFactory getInstance() {
if(theSecureStreamFactory==null) {
theSecureStreamFactory=new SecureStreamFactory();
}
return theSecureStreamFactory;
}
public InputStream getSecureInputStream(InputStream inputStream, Cipher theCipher) {
return new CipherInputStream(inputStream, theCipher);
}
public OutputStream getSecureOutputStream(OutputStream outputStream, Cipher theCipher) {
return new CipherOutputStream(outputStream, theCipher);
}
}
public class SecureSocketFactory implements RMIClientSocketFactory, Serializable {
private static int instanceCounter=0;
private int nInstance;
private Key theSecretKey;
public SecureSocketFactory() {
nInstance=instanceCounter;
instanceCounter++;
initSecretKey();
System.out.println("factory inizialized successfully!");
}
public Socket createSocket(String host, int port) throws IOException {
System.out.println("create socket factory constructor....");
if(port==9000) throw new RuntimeException("porta 9000 indisponibile");
return new NewSecureSocket(host, port, theSecretKey);
}
private void initSecretKey() {
try {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("C:/sistemi_distribuiti/key/asymmetric_key/pr_k_dc_s.dat"));
PrivateKey thePrivateKey=(PrivateKey) ois.readObject();
//va specificato il centro distribuzione chiavi
Socket s=new Socket("localhost", 9000);
PrintWriter pw=new PrintWriter(s.getOutputStream(), true);
pw.println("Socket");
DataInputStream in=new DataInputStream(s.getInputStream());
int length=in.readInt();
byte [] wrappedKey=new byte[length];
in.read(wrappedKey, 0, length);
in.close();
Cipher cipher=Cipher.getInstance("RSA", "BC");
cipher.init(Cipher.UNWRAP_MODE, thePrivateKey);
theSecretKey=cipher.unwrap(wrappedKey, "DES", Cipher.SECRET_KEY);
}
catch(Exception e) {
e.printStackTrace();
}
}
public int hashCode() {
return nInstance;
}
public boolean equals(Object o) {
return (getClass()==o.getClass() && nInstance==((SecureSocketFactory)o).nInstance);
}
public static void main(String [] args) {
RMIClientSocketFactory r=new SecureSocketFactory();
try {
Socket s=r.createSocket("localhost", 9000);
System.out.println(s.getClass());
}
catch(IOException e) {
e.printStackTrace();
}
}
}
public class SecureServerSocketFactory implements RMIServerSocketFactory {
private static int instanceCounter=0;
private int nInstance;
private Key theSecretKey;
public SecureServerSocketFactory() {
nInstance=instanceCounter;
instanceCounter++;
initSecretKey();
System.out.println("factory inizialized successfully!");
}
public ServerSocket createServerSocket(int port) throws IOException {
System.out.println("create server socket");
if(port==9000) throw new RuntimeException("porta 9000 indisponibile");
System.out.println("port: "+port);
System.out.println("theSecretKey: "+theSecretKey.toString());
return new NewSecureServerSocket(port, theSecretKey);
}
public int hashCode() {
return nInstance;
}
public boolean equals(Object o) {
return (getClass()==o.getClass() && nInstance==((SecureServerSocketFactory)o).nInstance);
}
private void initSecretKey() {
try {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("C:/sistemi_distribuiti/key/asymmetric_key/pr_k_dc_ss.dat"));
PrivateKey thePrivateKey=(PrivateKey) ois.readObject();
//va specificato l'indirizzo centro distribuzione chiavi
Socket s=new Socket("localhost", 9000);
PrintWriter pw=new PrintWriter(s.getOutputStream(), true);
pw.println("ServerSocket");
DataInputStream in=new DataInputStream(s.getInputStream());
int length=in.readInt();
byte [] wrappedKey=new byte[length];
in.read(wrappedKey, 0, length);
in.close();
Cipher cipher=Cipher.getInstance("RSA", "BC");
cipher.init(Cipher.UNWRAP_MODE, thePrivateKey);
theSecretKey=cipher.unwrap(wrappedKey, "DES", Cipher.SECRET_KEY);
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String [] args) {
RMIServerSocketFactory r=new SecureServerSocketFactory();
try {
ServerSocket s=r.createServerSocket(8000);
System.out.println(s.getClass());
}
catch(IOException e) {
e.printStackTrace();
}
}
}
public class NewSecureServerSocket extends ServerSocket{
private Key key;
public NewSecureServerSocket(int port, Key secretKey) throws IOException {
super(port);
this.key=secretKey;
}
public Socket accept() throws IOException {
Socket s=new NewSecureSocket(key);
this.implAccept(s);
return s;
}
}
public class NewSecureSocket extends Socket {
private Cipher ecipher, dcipher;
private SecureStreamFactory theSecureStreamFactory;
private Key theSecretKey;
private InputStream inputStream;
private OutputStream outputStream;
public NewSecureSocket(Key theSecretKey) throws IOException {
super();
this.theSecretKey=theSecretKey;
theSecureStreamFactory=SecureStreamFactory.getInstance();
}
public NewSecureSocket(String host, int port, Key theSecretKey) throws IOException {
super(host, port);
this.theSecretKey=theSecretKey;
theSecureStreamFactory=SecureStreamFactory.getInstance();
System.out.println("host: "+host);
System.out.println("port: "+port);
}
public synchronized OutputStream getOutputStream() throws IOException {
System.out.println("get output stream");
if(outputStream==null) {
try {
ecipher=Cipher.getInstance("DES", "BC");
ecipher.init(Cipher.ENCRYPT_MODE, theSecretKey);
outputStream=theSecureStreamFactory.getSecureOutputStream(super.getOutputStream(), ecipher);
}
catch(Exception e) {
e.printStackTrace();
}
}
return outputStream;
}
public synchronized InputStream getInputStream() throws IOException {
System.out.println("get input stream");
if(inputStream==null) {
try {
dcipher=Cipher.getInstance("DES", "BC");
dcipher.init(Cipher.DECRYPT_MODE, theSecretKey);
inputStream=theSecureStreamFactory.getSecureInputStream(super.getInputStream(), dcipher);
}
catch(Exception e) {
e.printStackTrace();
}
}
return inputStream;
}
}
public class KeyPairCreator {
private static String path="C:/sistemi_distribuiti/key/asymmetric_key/";
private static String file_pu_k_dc_s="pu_k_dc_s.dat";
private static String file_pr_k_dc_s="pr_k_dc_s.dat";
private static String file_pu_k_dc_ss="pu_k_dc_ss.dat";
private static String file_pr_k_dc_ss="pr_k_dc_ss.dat";
public static void main(String [] args) {
try {
File directory=new File(path);
if(!directory.exists()) {
directory.mkdirs();
}
KeyPairGenerator theKeyPairGenerator=KeyPairGenerator.getInstance("RSA", "BC");
SecureRandom secureRandom=new SecureRandom();
theKeyPairGenerator.initialize(128, secureRandom);
KeyPair theKeyPair=theKeyPairGenerator.generateKeyPair();
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(path+file_pu_k_dc_s));
oos.writeObject(theKeyPair.getPublic());
oos.close();
oos=new ObjectOutputStream(new FileOutputStream(path+file_pr_k_dc_s));
oos.writeObject(theKeyPair.getPrivate());
oos.close();
theKeyPair=theKeyPairGenerator.generateKeyPair();
oos=new ObjectOutputStream(new FileOutputStream(path+file_pu_k_dc_ss));
oos.writeObject(theKeyPair.getPublic());
oos.close();
oos=new ObjectOutputStream(new FileOutputStream(path+file_pr_k_dc_ss));
oos.writeObject(theKeyPair.getPrivate());
oos.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
public class KeyDistrCenter {
private static String path="C:/sistemi_distribuiti/key/asymmetric_key/";
private static String nameKey_DC_SS="pu_k_dc_ss.dat";
private static String nameKey_DC_S="pu_k_dc_s.dat";
private static Cipher cipher;
private static byte [] wrapped_DC_S_Key;
private static byte [] wrapped_DC_SS_Key;
public static void main(String [] args) {
try {
KeyGenerator keygen=KeyGenerator.getInstance("DES");
SecureRandom random=new SecureRandom();
keygen.init(random);
SecretKey key=keygen.generateKey();
wrapKey(nameKey_DC_S, key);
wrapKey(nameKey_DC_SS, key);
System.out.println("Key wrapped");
ServerSocket ss=new ServerSocket(9000);
while(true) {
Socket s=ss.accept();
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String req=br.readLine();
DataOutputStream out=new DataOutputStream(s.getOutputStream());
if(req.equals("Socket")) {
out.writeInt(wrapped_DC_S_Key.length);
out.write(wrapped_DC_S_Key);
}
else {
out.writeInt(wrapped_DC_SS_Key.length);
out.write(wrapped_DC_SS_Key);
}
out.close();
s.close();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
private static void wrapKey(String nameFile, Key key) {
try {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(path+nameFile));
Key publicKey=(Key) ois.readObject();
ois.close();
cipher=Cipher.getInstance("RSA", "BC");
cipher.init(Cipher.WRAP_MODE, publicKey);
if(nameFile.equals(nameKey_DC_SS)) {
wrapped_DC_SS_Key=cipher.wrap(key);
}
else {
wrapped_DC_S_Key=cipher.wrap(key);
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
public class HelloImpl implements Hello {
public HelloImpl() {}
public String sayHello() {
return "Hello World!";
}
public static void main(String [] args) {
try {
HelloImpl obj=new HelloImpl();
RMIClientSocketFactory csf=new SecureSocketFactory();
RMIServerSocketFactory ssf=new SecureServerSocketFactory();
Hello stub=(Hello) UnicastRemoteObject.exportObject(obj, 0, csf, ssf);
LocateRegistry.createRegistry(2002);
Registry registry=LocateRegistry.getRegistry(2002);
System.out.println("registry located...");
registry.rebind("Hello", stub);
System.out.println("HelloImpl bound in registry!");
}
catch(Exception e) {
e.printStackTrace();
}
}
}
public class HelloC {
public static void main(String [] args) {
try {
Registry registry=LocateRegistry.getRegistry(2002);
Hello obj=(Hello) registry.lookup("Hello");
String message=obj.sayHello();
System.out.println("message: "+message);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
public interface Hello extends Remote {
public String sayHello() throws RemoteException;
}
Thanks for all!!