Friday, February 21, 2014

Sending Java Sealed Objects via Sockets

Since I couldn't find a single example, this is a few examples put together into one working example, thought it'd be useful if I put it on the web

Here's a link to the Gist and below is the code https://gist.github.com/Sarkie/9138396

Server.java

import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import java.security.spec.*;
import java.security.*;

public class Server {  
 
  
    public static void main(String[] args) throws Exception {
     System.out.println("Server Started");
  
  // Create key
  final char[] password = "secret_password".toCharArray();
  final byte[] salt = "random_salt".getBytes();
  SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
  KeySpec spec = new PBEKeySpec(password, salt, 1024, 128);
  SecretKey tmp = factory.generateSecret(spec);
  SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

  Cipher dcipher = Cipher.getInstance("AES");
  dcipher.init(Cipher.DECRYPT_MODE, secret);   

     ServerSocketChannel ssChannel = ServerSocketChannel.open();
     ssChannel.configureBlocking(true);
     int port = 12345;
     ssChannel.socket().bind(new InetSocketAddress(port));

     while (true) {
   System.out.println("Waiting for a connection...");
      SocketChannel sChannel = ssChannel.accept();

   System.out.println(sChannel.getRemoteAddress().toString() +" connected");
      
   ObjectInputStream ois = new ObjectInputStream(sChannel.socket().getInputStream());

   SealedObject s = (SealedObject)ois.readObject();
   
   SecretObject decryptedSecretObject = (SecretObject) s.getObject(dcipher);     
   
      System.out.println("Server - Packet Data is: '" + decryptedSecretObject.getSecretMessage() + "'");
   
   ois.close();

      System.out.println("Connection ended");
     }
    }
}

Client.java

import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import java.security.spec.*;
import java.security.*;

public class Client {

    public static void main(String[] args) throws Exception {
 
  String server = "localhost";
  
  if(args.length == 1){
   server = args[0];
  }
 
     System.out.println("Receiver Started");
  
  // Create key
  final char[] password = "secret_password".toCharArray();
  final byte[] salt = "random_salt".getBytes();
  SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
  KeySpec spec = new PBEKeySpec(password, salt, 1024, 128);
  SecretKey tmp = factory.generateSecret(spec);
  SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

  Cipher cipher = Cipher.getInstance("AES");
  cipher.init(Cipher.ENCRYPT_MODE, secret);   

     SocketChannel sChannel = SocketChannel.open();
     sChannel.configureBlocking(true);
  
     if (!sChannel.connect(new InetSocketAddress(server, 12345))) {
   System.out.println("Cannot connect to Server, make sure it is running");
  }
   
  ObjectOutputStream  oos = new ObjectOutputStream(sChannel.socket().getOutputStream());

  SecretObject secretObject = new SecretObjectImpl("007");

  SealedObject so = new SealedObject(secretObject, cipher);

  oos.writeObject(so);
  System.out.println("Sent Sealed Object");

  oos.close();     

     System.out.println("End Receiver");
    }
}

SecretObject.java

import java.io.*;

public interface SecretObject extends Serializable {
   String getSecretMessage();
}

SecretObject.java

import java.io.*;

public class SecretObjectImpl implements SecretObject {
 
 private String _secretMessage = "";
 
 public SecretObjectImpl(String secretMessage) {
  _secretMessage = secretMessage;
 }

 public String getSecretMessage() {
  return _secretMessage;
    }

}