End-to-End Encrypted Chat

Implementing an end-to-end encrypted chat program.

One of the courses I was enrolled in as a second year undergraduate was called Team Software Project, and the goal of the course was to build a project of our choice with a group of other students. My group consisted of four people, and we decided we wanted to build something utilizing encryption, because a number of  group members were currently taking cryptography course work.

Our project ended up being an encrypted chat program (utilizing the RSA algorithm) with a server and client paradigm that was conceptually similar to an instant messenger. Due to time constraints, each client had to manually enter: the hostname of the server, the port number the server was running on, a username, and information about the public and private components of their RSA key. When the client connects to the server, the server keeps a running list of who is connected, and what their public key information is. Each client then can enter a recipient that they would like to message with, who is also connected to the server, and send a message to them. When a message is sent to a recipient the client requests the recipient's public key from the server, encrypts the message via the public key, and sends it to the recipient. Due to the asymmetric nature of RSA, anyone eavesdropping the connection would have to know the private key in order to decrypt the contents of the message, so only the intended recipient who has the private key would be able to view the message. Our implementation was simple in terms of features, but proved to be a good proof of concept. There were three main components that were developed in this project: the encryption, the client, and the server.

Encryption

Most of the implementation for the encryption was done by other members of the group. We initially were going to use BouncyCastle, since rolling your own encryption is a big faux pas, but some of the group members wanted to further their knowledge of RSA, and decided to implement the encryption themselves. The chat program required the n, e, and d values that are needed for RSA to be manually entered. These values are integral to a strong RSA implementation, so instead of selecting a value automatically the program put this problem into the user's hand (choosing good keys is an essential, but challenging, detail in an RSA implementation).

Client

The client GUI for the program was written in Java Swing utilizing grid layouts. I helped out intermittently with the GUI, but most of my work was in creating the net and thread code to handle sending and receiving messages, and connecting clients to the server. The client GUI interfaces with a separate client thread, which handles sending, receiving, and encrypting messages being sent. The client thread also watches for messages from the server that it can decrypt and display, and makes requests for the public keys of recipients that the user would like to message.

Server

The server runs from the command line and creates a server socket for clients to connect to. Each connected client is given a thread to handle communication and other requests from the client. The server also has a dedicated thread called the client listing. As the name suggests, the client listing is a mapping on the server from each username to the thread and public key that is used to communicate with them. The server allows an arbitrary number of clients to connect to it (barring memory or performance issues), and clients can communicate with any other client they wish to. We did not implement client lists as something visible to the clients, so while the server knows who is connected to it, the clients need to know who they want to talk to.