DavidKroukamp 105 Master Poster Team Colleague Featured Poster

For now the code isn't to complex. Built in Netbeans 7 java 6.... just the basis for now but its very safe connection so thought i'd post it for anyone who needs it.

A quit command may be sent to any client by specifying its ID and then press enter and type 'quit' and enter again client should be stopped now.

/** Server:  */
package jBotnet; //name of package

//imports needed
import java.io.*;
import javax.net.ssl.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.regex.*;
import sun.misc.*;

//Author: cOrRuPt G3n3t!x
//Tested on: Windows XP x86, WIndows 7 x64 and Windows 7 x86.
public class jBotServer extends Thread {

    /*
    This is a multithreaded server app that uses ssl/tls type encryption called
    anonymous sll and is (of course) less secure than the certified one, hence why there is no need for
    certificates etc. There are multiple cipher suuites for both the client and server to choose from 
    however AES is the higher prioritized encryption used for the ssl/tls, a pattern matcher and for loop used to set the 
    array of available encryption suites for ssl/tls AES 128bit as higher prioriries i.e first in array. It also encrypts 
    data with AES 128bit so alls pretty safe, also all data is encoded and decoded  and from  base64, after encrypting and
    before decrypting respectively - Helps to  prevent data from getting *messed* up because of the dumb *stuff* when strings go
    to byte arrays and vice versa    on 'getBytes()' and 'new String()'. The client generates and sends the key used for the 
    session encoded in base64 but otherwise unencrypted - other than the sll encryption ofcourse - how can we use the AES if 
    the server hasnt got the key yet ;). From there after all data to and from that client is encrypted using that key. all
    clients generate new keys on accessing the sever.
     */
    static int count = 1;
    SSLSocket m_clientSocket;
    int m_clientID = -1;
    static int[] clientid = new int[100];
    static SSLSocket[] clientsocket = new SSLSocket[100];
    static Cipher[] cipher = new Cipher[100];
    static SecretKeySpec[] skeySpec = new SecretKeySpec[100];
    //code starts here

    public static void main(String[] args) throws IOException {

        //initiate variables for a ssl server socket
        SSLServerSocket sslServerSocket = null;
        SSLSocket sslSocket = null;

        try {

            int port = 8181;//port 8181 this is where server wil listen for clients

            //creates the server on the port using SSL and binds itself to port
            SSLServerSocketFactory sslSrvFact = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
            sslServerSocket = (SSLServerSocket) sslSrvFact.createServerSocket(port);

            System.out.println("Listening for clients on " + port + " ...");

        } catch (Exception e) {//if an error occurs while creating a server socket on the specivied port

            System.out.println("Exception occured: " + e + " Closing the server socket now.");

            //end connection on the socket and port
            sslSocket.close();
            sslServerSocket.close();
            System.exit(0); //now exit because we couldnt listen for clients
        }

        // Successfully created Server Socket. Now wait for connections. 
        int id = 1, counter = 1;
        //array used to save clients information, maximum clients for testing is 100 if this is surpassed the client data wont be saved in array!


        while (true) {
            try {
                // Accept incoming connections. 

                sslSocket = (SSLSocket) sslServerSocket.accept();

                // accept() will block until a client connects to the server. 
                // If execution reaches this point, then it means that a client 
                // socket has been accepted. 

                // For each client, we will start a service thread to 
                // service the client requests. This is to demonstrate a 
                // multithreaded server.

                // Start a service thread 
                jBotServer ct = new jBotServer(sslSocket, id++);
                ct.start();

                //save information of all clients in array;
                clientid[counter] = id - 1;
                clientsocket[counter] = sslSocket;

                counter++;//increase counter for next client
            } catch (IOException ioe) {
                System.out.println("Exception encountered on accept. Ignoring... and listening for other clients");
            }
        }
    }

    jBotServer(SSLSocket s, int clientID) {
        m_clientSocket = s;
        m_clientID = clientID;
    }

    @Override
    public void run() {
        BufferedReader in = null;
        PrintWriter out = null;
        try {

            // Pick all AES algorithms of 128 bits key size not 256 this is not natively suporrted by java and has flaws
            String patternString = "AES.*128";
            Pattern pattern = Pattern.compile(patternString);
            Matcher matcher;
            boolean matchFound = false;

            // Print out details of this connection 
            System.out.println("Accepted Client : ID - " + m_clientID + " : Address - " + m_clientSocket.getInetAddress().getHostName());

            String cipherSuites[] = m_clientSocket.getSupportedCipherSuites();

            int len = cipherSuites.length;
            String prioritizedCipherSuites[] = new String[len];

            int j = 0, k = len - 1;
            for (int i = 0; i < len; i++) {

                //System.out.println(cipherSuites[i]); 

                // Determine if pattern exists in input
                matcher = pattern.matcher(cipherSuites[i]);
                matchFound = matcher.find();

                if (matchFound) {
                    prioritizedCipherSuites[j++] = cipherSuites[i];
                } else {
                    prioritizedCipherSuites[k--] = cipherSuites[i];
                }
            }
            m_clientSocket.setEnabledCipherSuites(prioritizedCipherSuites);

            System.out.println("Using cipher suite: " + (m_clientSocket.getSession()).getCipherSuite());

            // At this point, we can read for input and reply with appropriate output. 
            in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
            out = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()));

            //propritary api might be removed fututre java versions. maybe use hex then
            BASE64Encoder encoder = new BASE64Encoder();
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] db = decoder.decodeBuffer(in.readLine());
            skeySpec[count] = new SecretKeySpec(db, "AES");
            cipher[count] = Cipher.getInstance("AES");
            count++;
            while (true) {
                BufferedReader br = null;
                InputStreamReader isr = null;
                System.out.println("Enter a id.");
                isr = new InputStreamReader(System.in);
                br = new BufferedReader(isr);
                String clientCommand = br.readLine();
                for (int i = 0; i < clientsocket.length; i++) {
                    if (clientid[i] == Integer.parseInt(clientCommand)) {
                        in = new BufferedReader(new InputStreamReader(clientsocket[i].getInputStream()));
                        out = new PrintWriter(new OutputStreamWriter(clientsocket[i].getOutputStream()));
                        System.out.println("Enter a command");
                        isr = new InputStreamReader(System.in);
                        br = new BufferedReader(isr);
                        clientCommand = br.readLine();
                        //get user input
                        String msgs = encoder.encode(encrypt(cipher[i], skeySpec[i], clientCommand));
                        out.println(msgs);
                        out.flush();

                        byte[] encryptedIncomingData = decoder.decodeBuffer(in.readLine());
                        clientCommand = decrypt(cipher[i], skeySpec[i], encryptedIncomingData);
                        System.out.println("Client " + clientid[i] + " says: " + clientCommand);
                        break;
                    }
                }
            }

        } catch (Exception ex) {

            try {
                System.out.println("Client " + m_clientID + "...stopped");
                in.close();
                out.close();
                m_clientSocket.close();
            } catch (IOException ex1) {
            }

        }
    }

    public static byte[] encrypt(Cipher cipher, SecretKeySpec skeySpec, String msg) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal((msg).getBytes());
        return encrypted;
    }

    public static String decrypt(Cipher cipher, SecretKeySpec skeySpec, byte[] encrypted) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] original = cipher.doFinal(encrypted);
        String originalString = new String(original);
        return originalString;
    }
}
/** client */
package jBotnet; //name of package

//imports needed
import java.io.*;
import javax.net.ssl.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.regex.*;
import sun.misc.*;

//Author: cOrRuPt G3n3t!x
//Tested on: Windows XP x86, WIndows 7 x64 and Windows 7 x86.
public class jBotClient {

    /*
    This is a multithreaded server app that uses ssl/tls type encryption called
    'anonymous sll' and is (of course) less secure than the certified one, hence why there is no need for
    certificates etc. There are multiple cipher suuites for both the client and server to choose from 
    however AES is the higher prioritized encryption used for the ssl/tls, a pattern matcher and for loop used to set the 
    array of available encryption suites for ssl/tls AES 128bit as higher prioriries i.e first in array. It also encrypts 
    data with AES 128bit so alls pretty safe, also all data is encoded and decoded  and from  base64, after encrypting and
    before decrypting respectively - Helps to  prevent data from getting *messed* up because of the dumb *stuff* when strings go
    to byte arrays and vice versa    on 'getBytes()' and 'new String()'. The client generates and sends the key used for the 
    session encoded in base64 but otherwise unencrypted - other than the sll encryption ofcourse - how can we use the AES if 
    the server hasnt got the key yet ;). From there after all data to and from that client is encrypted using that key. all
    clients generate new keys on accessing the sever.
     */
    //code starts here
    public static void main(String[] args) throws IOException {
        // Pick all AES algorithms of 128 bits key size because 256bit is not natively supported by the keygenerator and has flaws 128 is still best
        String patternString = "AES.*128";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher;
        boolean matchFound = false;
        BufferedReader in = null;
        PrintWriter out = null;
        SSLSocket sslSocket = null;

        try {

            SSLSocketFactory sslFact = (SSLSocketFactory) SSLSocketFactory.getDefault();
            sslSocket = (SSLSocket) sslFact.createSocket("127.0.0.1", 8181);
            String cipherSuites[] = sslSocket.getSupportedCipherSuites();

            int len = cipherSuites.length;
            String prioritizedCipherSuites[] = new String[len];

            int j = 0, k = len - 1;
            for (int i = 0; i < len; i++) {
                //System.out.println(cipherSuites[i]); 
                // Determine if pattern exists in input
                matcher = pattern.matcher(cipherSuites[i]);
                matchFound = matcher.find();

                if (matchFound) {
                    prioritizedCipherSuites[j++] = cipherSuites[i];
                } else {
                    prioritizedCipherSuites[k--] = cipherSuites[i];
                }
            }

            sslSocket.setEnabledCipherSuites(prioritizedCipherSuites);
            System.out.println("Using cipher suite: " + (sslSocket.getSession()).getCipherSuite());
            // Get the KeyGenerator
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            keygen.init(128); // 192 and 256 bits may not be available

            // Generate the secret key specs.
            SecretKey skey = keygen.generateKey();
            byte[] raw = skey.getEncoded();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            //can open streams to recieve data
            in = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
            out = new PrintWriter(new OutputStreamWriter(sslSocket.getOutputStream()));
            //propritary api might be removed fututre java versions. maybe use hex then
            BASE64Decoder decoder = new BASE64Decoder();
            BASE64Encoder encoder = new BASE64Encoder();
            String eb = encoder.encode(raw);
            out.println(eb);  //send server the aes key for this session
            out.flush();
            while (true) {
                // receive the reply. 
                byte[] serverCommand = decoder.decodeBuffer(in.readLine());
                String sevCmd = decrypt(cipher, skeySpec, serverCommand);
                System.out.println("Server says: " + sevCmd);
                if (sevCmd.equalsIgnoreCase("quit")) {
                    String clientreply = "quiting....";
                    String msgs = encoder.encode(encrypt(cipher, skeySpec, clientreply));
                    out.println(msgs);
                    out.flush();
                    out.close();
                    in.close();
                    sslSocket.close();
                    System.exit(0);
                }
                String clientreply = "replying....";
                String msgs = encoder.encode(encrypt(cipher, skeySpec, clientreply));
                out.println(msgs);
                out.flush();
            }
        } catch (Exception e) {
            System.out.println("Exception " + e);
            sslSocket.close();
        }
    }

    public static byte[] encrypt(Cipher cipher, SecretKeySpec skeySpec, String msg) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal((msg).getBytes());
        return encrypted;
    }

    public static String decrypt(Cipher cipher, SecretKeySpec skeySpec, byte[] encrypted) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] original = cipher.doFinal(encrypted);
        String originalString = new String(original);
        return originalString;
    }
}