An implementation of a primitive secure communications system utilizing the RSA cryptosystem and two primitive symmetric ciphers – a substitution cipher and an additive cipher. I completed this project for a University assignment.
Do not use any of the source code to submit as your own work or idea.
Program Written in November 2020
Pushed to Github in December 2020
RSAChatServer.java allows multiple clients to connect to it and send messages amongst each other. The messages are encrypted prior to being sent to the chat group. As the server, it receieves every message sent by a client and then forwards that message to all other clients.
RSAChatClient.java operates as the client. It opens a connection to the server via a Socket at the server's IP Address and port. The port number is set at 4444. The client will prompt for the server name. Use localhost as the server's name if it is being run on a local machine. The client receives both the server's public key, E and the server's public mod value, N as BigInteger objects. The server also sends the preferred symmetric cipher as a String object and the client creates a corresponding object of either
Substitution or Additive. It converts the key from the chosen symmetric cipher to a BigInteger object. After RSA-encytping the BigInteger version using the public key and public mod key, the encrypted BigInteger key is sent to the server. The user's username is also encrypted and sent to the server when entered. The encode() method does the encryption and returns the corresponding array of bytes to the server. The decode() method decrypts the message that is sent before posting it on the chat window.
SymmetricCipher.java is an interface for the two symmetric cipher types. It containing methods to getKey(), encode(), and decode().
Additive.java is one of the types of symmetric ciphers that can be used. The class has two constructors. The first constructor creates a randomized 128-byte additive key that will be stored in an array of bytes. The second constructor uses this array of bytes as a key. RSAChatServer.java will call the parameterized constructor while RSAChatClient.java calls the constructor with no parameter. The decryption occurs by subtracting the corresponding byte of the key from each index of the array of bytes. If the sent message is shorter than the key, then the remaining bytes are ignored. If the sent message is longer than the key, then the key is cycled through as needed. The byte array is converted in decryption and returned as a String.
Substitution.java is the second type of symmetric cipher that can be used. The class has two constructors. The first constructor creates a randomized 256-byte array. This is a permutation of the 256 possible byte values and serves as a map from bytes to the actual substitution values. This is the reason that an inverse mapping array that is derived from the substitution array is used. The second constructor takes in the parameter of the byte array and uses it as a key. RSAChatServer.java will call the parameterized constructor while RSAChatClient.java calls the constructor with no parameter. Decryption is achieved by reversing the substitution and converting the bytes to a String to be returned.
COMPILATION:
javac RSAChatServer.java
EXECUTION:
java RSAChatServer
COMPILATION:
javac RSAChatClient.java
EXECUTION:
java RSAChatClient
Compile and run the server in one terminal first. Open a second and third terminal and compile and run the client in each. Use localhost as the 'Server Name' for both clients. The E and N keys and the type of cipher will be outputted to the console. The symmetric key generated by each client will also be outputted. For each message that is encrypted, the original message as a String, the corresponding array of bytes and the encrypted array of bytes will all be outputted. For each message that is decrypted, the array of bytes recieved, the decrypted array of bytes and the corresponding message as a String will all be outputted.